1

我有这个简单的代码:

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.

我不明白出了什么问题,在另一个项目中非常相似的代码可以工作。谢谢!

更新,更多代码:

    [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);
4

1 回答 1

3

您所展示的最明显的缺陷是您试图将 64 位指针作为 32 位值传递,这显然无法正常工作。该ordersCallbackAddress_参数被声明为long32 位宽。但是你显然有一个 64 位进程。这几乎可以肯定地解释了您遇到的错误。

请记住,在 Windows 上的 C++ 中,long它是 32 位宽的。在 C# 中,它是 64 位宽。在任何情况下,您都不应该使用整数类型来传递指针。如果您有指针,请将您的函数设计为对指针进行操作。

您需要确保将ordersCallbackAddress_其声明为指针大小。我不明白为什么它没有被声明为OrdersCallback.

可能还有其他问题,但是您没有显示很多代码。您没有显示结构声明或接口托管端的任何内容。

于 2013-06-20T12:06:06.083 回答