Mik*_*e G 2 c# pinvoke dllimport
这是我的C代码:
LIBRARY_API bool __cdecl Initialize(void (*FirstScanForDevicesDoneFunc)(void));
Run Code Online (Sandbox Code Playgroud)
这是使用此DLL的C#PINvoke代码:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FirstScanForDevicesDoneFunc();
[DllImport("Native.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern bool Initialize(FirstScanForDevicesDoneFunc);
Run Code Online (Sandbox Code Playgroud)
当我这样调用这个方法时:
static public void Init() {
Initialize(FirstScanForDevicesDone);
}
static public void FirstScanForDevicesDone() {
//do something
}
Run Code Online (Sandbox Code Playgroud)
在Init()回调结束时,我得到NullReferenceException.所以我使用Thread来保持它并且一切正常,但我对这个解决方案不满意:
static public bool Working = true;
static public void Init() {
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Initialize(FirstScanForDevicesDone);
while (Working)
{
Thread.Sleep(1000);
}
}).Start();
}
Run Code Online (Sandbox Code Playgroud)
是否有更复杂的方法来保持这种工作?
Han*_*ant 10
所以我使用Thread来保持它,一切正常
不,该线程实际上没有解决问题.它只是看起来像,测试Debug构建和使用调试器的副作用.将Release版本发布给客户后,它仍会以完全相同的方式崩溃.最糟糕的当然是失败.在这篇文章中解释了为什么线程似乎解决了它.
您需要解决实际问题,您将委托对象传递给本机代码,但在Init()方法完成后,对该对象不再有可见的引用.垃圾收集器无法查看本机代码以查看其中的使用情况.因此,当本机代码在此之后进行回调时,下一个垃圾收集将破坏对象kaboom.请注意,您通常会从调试器助手那里得到一个措辞强烈的警告,确保您没有通过拍摄信使来解决问题.
正确的解决方法是:
static FirstScanForDevicesDoneFunc callbackDelegate;
static public void Init() {
callbackDelegate = new FirstScanForDevicesDoneFunc(FirstScanForDeviceDone);
Initialize(callbackDelegate);
}
Run Code Online (Sandbox Code Playgroud)
所述callbackDelegate变量确保GC总能看到的对象的引用.当本机代码不能再进行回调时,将其设置为null.通常从不.
| 归档时间: |
|
| 查看次数: |
250 次 |
| 最近记录: |