Tom*_*omO 6 c# c++ c++-cli callback access-violation
所以我有一个我正在使用的本地第三方C++代码库(.lib和.hpp文件),我曾经在C++/CLI中构建一个包装器,以便最终在C#中使用.
从调试模式切换到发布模式时,我遇到了一个特殊问题,因为当回调代码返回时,我遇到了一个访问冲突异常.
来自原始hpp文件的代码用于回调函数格式:
typedef int (*CallbackFunction) (void *inst, const void *data);
Run Code Online (Sandbox Code Playgroud)
来自C++/CLI Wrapper的代码用于回调函数格式:(我将解释为什么我暂时宣布两个)
public delegate int ManagedCallbackFunction (IntPtr oInst, const IntPtr oData);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);
Run Code Online (Sandbox Code Playgroud)
- 很快,我宣布第二个"UnManagedCallbackFunction"的原因是我试图在包装器中创建一个"中间"回调,因此链从Native C++> C#更改为Native C++> C++/CLI Wrapper> C#的版本...完全公开,问题仍然存在,它刚刚被推送到C++/CLI Wrapper现在在同一行(返回).
最后,来自C#的崩溃代码:
public static int hReceiveLogEvent(IntPtr pInstance, IntPtr pData)
{
Console.WriteLine("in hReceiveLogEvent...");
Console.WriteLine("pInstance: {0}", pInstance);
Console.WriteLine("pData: {0}", pData);
// provide object context for static member function
helloworld hw = (helloworld)GCHandle.FromIntPtr(pInstance).Target;
if (hw == null || pData == null)
{
Console.WriteLine("hReceiveLogEvent: received null instance pointer or null data\n");
return 0;
}
// typecast data to DataLogger object ptr
IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataLoggerWrap(pData)));
DataLoggerWrap dlw = (DataLoggerWrap)GCHandle.FromIntPtr(ip2).Target;
//Do Logging Stuff
Console.WriteLine("exiting hReceiveLogEvent...");
Console.WriteLine("pInstance: {0}", pInstance);
Console.WriteLine("pData: {0}", pData);
Console.WriteLine("Setting pData to zero...");
pData = IntPtr.Zero;
pInstance = IntPtr.Zero;
Console.WriteLine("pData: {0}", pData);
Console.WriteLine("pInstance: {0}", pInstance);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
对控制台的所有写入都已完成,然后我们在返回时看到可怕的崩溃:
helloworld.exe中0x04d1004c处的未处理异常:0xC0000005:访问冲突读取位置0x04d1004c.
如果我从这里进入调试器,我看到的是调用堆栈上的最后一个条目是:>"04d1004c()",它的计算结果为十进制值:80805964
如果你看一下控制台显示:
entering registerDataLogger
pointer to callback handle: 790848
fp for callback: 2631370
pointer to inst: 790844
in hReceiveLogEvent...
pInstance: 790844
pData: 80805964
exiting hReceiveLogEvent...
pInstance: 790844
pData: 80805964
Setting pData to zero...
pData: 0
pInstance: 0
Run Code Online (Sandbox Code Playgroud)
现在,我知道在调试和发布之间,微软世界中有些东西是完全不同的.我当然担心字节填充和变量的初始化,所以如果我在这里没有提供的东西,请告诉我,我将添加(已经很长)的帖子.我还认为托管代码可能不会释放所有所有权,然后原生C++内容(我没有代码)可能会尝试删除或终止pData对象,从而导致应用程序崩溃.
更全面的披露,它在调试模式下运行良好(貌似)!
一个真正的头部划痕问题,将不胜感激任何帮助!
我认为堆栈由于调用约定不匹配而被压垮:尝试放置属性
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
Run Code Online (Sandbox Code Playgroud)
在回调委托声明上。
归档时间: |
|
查看次数: |
6831 次 |
最近记录: |