所以我有一个本土的第三方C ++代码库,我与我用来建立在C#中最终使用在C ++ / CLI的包装(.LIB和.HPP文件)工作。
我从调试切换到发布模式时,碰到一个特殊的问题,因为我得到一个访问冲突异常时一个回调的代码返回。
从回调函数的格式原来的HPP文件的代码:
typedef int (*CallbackFunction) (void *inst, const void *data);
从C ++ / CLI包装代码以便回调函数格式:(我会解释为什么我在某一时刻宣布二)
public delegate int ManagedCallbackFunction (IntPtr oInst, const IntPtr oData);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);
--Quickly,原因我声明一个第二“UnManagedCallbackFunction”是我试图创建在包装的“中介”回调,所以链条从本机C ++> C#改变为版本的本机C ++> C ++ / CLI包装> C# ......充分披露,问题仍然生活,它只是被推迟到C ++ / CLI包装现在在同一行(返回)。
最后,从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;
}
所有控制台写操作完成,然后我们看到了回报可怕的崩溃:
在0x04d1004c HelloWorld.exe的中未处理的异常:0000005:访问冲突读取位置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
现在,我知道,调试之间并释放出一些东西都在微软的世界完全不同。 我当然担心字节填充和变量的初始化,所以如果有什么我这里不提供,只是让我知道,我会加入到(已经长)职务。 我也认为,托管代码可能不释放所有所有权,然后在本地C ++的东西(我不具备的代码)可能试图删除或杀死的对象pData中,从而崩溃的应用程序。
更充分披露,这一切工作正常(貌似)在调试模式下!
一个真正的头划伤的问题是希望得到任何帮助!