Pav*_*ska 7 .net c# dllimport access-violation glfw
我有一个glfwSetCharCallback函数的问题.每当我调用它时,glfwPollEvents都会抛出一个AccessViolationException:"试图读取或写入受保护的内存.这通常表明其他内存已损坏."
我创建了一个非常简单的包装器来演示问题:
using System;
using System.Runtime.InteropServices;
using System.Security;
namespace Test
{
public delegate void GlfwCharCallback(GlfwWindow window, Char character);
[StructLayout(LayoutKind.Explicit)]
public struct GlfwMonitor
{
private GlfwMonitor(IntPtr ptr)
{
_nativePtr = ptr;
}
[FieldOffset(0)] private readonly IntPtr _nativePtr;
public static readonly GlfwMonitor Null = new GlfwMonitor(IntPtr.Zero);
}
[StructLayout(LayoutKind.Explicit)]
public struct GlfwWindow
{
private GlfwWindow(IntPtr ptr)
{
_nativePtr = ptr;
}
[FieldOffset(0)] private readonly IntPtr _nativePtr;
public static GlfwWindow Null = new GlfwWindow(IntPtr.Zero);
}
public class Wrap
{
[DllImport("GLFW3", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
private static extern Int32 glfwInit();
[DllImport("GLFW3", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
internal static extern GlfwWindow glfwCreateWindow(Int32 width, Int32 height,
[MarshalAs(UnmanagedType.LPStr)] String title,
GlfwMonitor monitor, GlfwWindow share);
[DllImport("GLFW3", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
internal static extern void glfwSetCharCallback(GlfwWindow window, GlfwCharCallback callback);
[DllImport("GLFW3", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
internal static extern void glfwPollEvents();
public static Boolean Init()
{
return glfwInit() == 1;
}
public static GlfwWindow CreateWindow(Int32 width, Int32 height, String title, GlfwMonitor monitor,
GlfwWindow share)
{
return glfwCreateWindow(width, height, title, monitor, share);
}
public static void SetCharCallback(GlfwWindow window, GlfwCharCallback callback)
{
glfwSetCharCallback(window, callback);
}
public static void PollEvents()
{
glfwPollEvents();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我称它为GLFW:
using System;
namespace Test
{
class Program
{
static void Main()
{
Wrap.Init();
var window = Wrap.CreateWindow(800, 600, "None", GlfwMonitor.Null, GlfwWindow.Null);
Wrap.SetCharCallback(window, (glfwWindow, character) => Console.WriteLine(character));
while(true)
{
Wrap.PollEvents();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该字符被打印到控制台,我得到AccessViolationException.
我做错了什么?所有的DllImports都指定了CDecl调用约定(我在PollEvents和SetCharCallback上都试过了其他的),我在SetCharCallback函数上尝试了所有的CharSets并且没有任何效果.
有人可以帮帮我吗?
这是我正在使用的GLFW3 Dll:http://www.mediafire.com/? n4uc2bdiwdzddda
使用最新的"lib-msvc110"DLL使glfwSetCharCallback工作.glfwSetKeyCallback和glfwSetCursorPosCallback不起作用并继续抛出AccessViolationException.我将试图弄清楚是什么让CharCallback变得如此特别,但老实说,我已经完成了GLFW源代码,并且所有函数似乎都以同样的方式完成了它们的工作.也许有一些我忽略的东西.
我已经尝试了所有的东西,cdecl,stdcall,所有的字符集,所有版本的dll,所有的参数组合等等.我已经确保回调没有通过存储对它们的引用来处理.我还试图通过不保留glfwSetCharCallback(现在的工作原理)的任何参数空间来故意使应用程序崩溃,而我还没有设法做到这一点.这让我相信论证本身与应用无关.
真正让我认为错误的是GLFW本身的事实是,如果我针对x86-64 dll进行编译,那么一切都很完美.在x86-64上使用cdecl有点奇怪,因为MSDN特别指出唯一的调用约定是fastcall.
我花了一段时间,但我解决了。所有委托都描述 C# 函数,无法从 C 调用。解决方案是让委托描述类似 C 的函数,这可以通过属性来实现UnmanagedFunctionPointer。
向所有委托添加该属性(如下所示)解决了该问题。
[UnmanagedFunctionPointer(CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public delegate void GlfwCharCallback(GlfwWindow window, Char character);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
805 次 |
| 最近记录: |