当尝试调用c#回调时,AccessViolationException
AccessViolationException when trying to call c# callback
我有这个简单的代码:
typedef void (__stdcall * OrdersCallback)(ordersTest*);
__declspec(dllexport) void InitializeCallbacks(long ordersCallbackAddress_) {
OrdersCallback ordersCallbackFunction;
std::cout << "current ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
std::cout << "set ordersCallbackAddress_ = " << ordersCallbackAddress_ << std::endl;
ordersCallbackFunction = (OrdersCallback) ordersCallbackAddress_;
std::cout << "new ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
ordersTest test;
test.replID = 123;
std::cout << "use ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
ordersCallbackFunction(&test);
}
当回调调用时,引发AccessViolationException:
current ordersCallbackFunction = 000007F92BC354E0 address = 0000009785D1EC68
set ordersCallbackAddress_ = -2043003524
new ordersCallbackFunction = FFFFFFFF863A3D7C address = 0000009785D1EC68
use ordersCallbackFunction = FFFFFFFF863A3D7C address = 0000009785D1EC68
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
我不明白是什么错了,在另一个项目非常相似的代码工作。谢谢!
upd,更多代码:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void OrdersCallback(ref OrdersTest value);
[DllImport("CGateNativeAdapter.dll"), SuppressUnmanagedCodeSecurity]
public static extern void InitializeCallbacks(
[MarshalAs(UnmanagedType.FunctionPtr)] OrdersCallback ordersSnapshotCallbackPointer);
OrdersCallback ordersCallback =
delegate(ref OrdersTest value)
{
Console.WriteLine("C# Orders call received = " +
" replID = " + value.replID);
};
InitializeCallbacks(ordersCallback);
您所显示的最明显的缺陷是您试图将64位指针传递为32位值,这显然无法工作。ordersCallbackAddress_
参数声明为long
,其宽度为32位。但你显然有一个64位的进程。这几乎可以肯定地解释您正在经历的错误。
请记住,在Windows上的c++中,long
是32位宽。在c#中是64位宽。在任何情况下都不应该使用整型传递指针。如果你有一个指针,把你的函数设计成对指针进行操作。
您需要确保将ordersCallbackAddress_
声明为指针大小。我不明白为什么不声明为OrdersCallback
。
可能还有其他问题,但您没有显示太多代码。您没有在接口的托管端显示结构声明或任何内容。
相关文章:
- C++/CLI System.AccessViolation在托管类中调用非托管函数时出现异常
- 堆栈溢出后调用SymSetOptions时发生AccessViolation
- Visual C#在调用包装的C++CLI dll中的Lapack时引发System.AccessViolation
- c# unmanaged PInvoke AccessViolation
- AccessViolation调试有趣
- AccessViolation仅在优化的Win32构建(XMMATRIX)
- 在c++中使用_tcstock时出现AccessViolation错误
- Cocos2d-x CCSprite->setDisplayFrame AccessViolation crash