【问题标题】:Stuck on calling convention calling Managed CLI method from unmanaged C++坚持从非托管 C++ 调用托管 CLI 方法的调用约定
【发布时间】:2013-04-28 16:00:15
【问题描述】:

我正在尝试从非托管代码调用托管方法。但是,托管代码要求我使用 '(__clrcall) 调用约定,而我的非托管 C++ 代码拒绝让我在不使用 /clr 选项的情况下使用 __clrcall 调用约定。我不相信我想这样做,因为非托管项目不是我要更改为托管的。

正如我在 CodeGuru 和 MSDN 上看到的那样,我已经在托管端构建了所有这些委托和函数指针封送处理,但这个错误仍然会弹出,除非我使用不能成为成员的 __stdcall 约定调用静态函数参考类。该方法需要是 ref 类的实例。

我能够解决这个问题的唯一方法是从程序集中的非托管代码中执行我的方法调用,在调用之后跳过 ESP 寄存器的弹出(添加 4)(调用在参数中有一个参数因此'4')。这使我能够有效地进行 __clrcall。这个选项很臭。

有人对如何解决此问题有任何想法吗?这肯定是可能的。我遗漏了一些简单但重要的信息。

这是我的委托定义(所有这些都属于单个 ref 类 ManagedSensor):

        delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);

这是我要调用的实例方法

        void LocalOxpMeasurementCallback(std::vector<OBX> *obxes);

这里是 ref 类函数到 ref 类构造函数中的非托管函数的编组:

    // Now to make the 'delegate' unmanaged function pointer usable for unmanged code
    // The argument is the unmanaged callback.
    OxpOnReceivedMeasurement ^oxpMeasurementCallbackFP = gcnew OxpOnReceivedMeasurement(this, &ManagedSensor::LocalOxpMeasurementCallback);
    // Lock it so the garbage collector doesnt get rid of it or move it
    gch = GCHandle::Alloc(oxpMeasurementCallbackFP);
    // Pass the marshaled function pointer to the unmanaged code
    IntPtr ip = Marshal::GetFunctionPointerForDelegate(oxpMeasurementCallbackFP);
    // fnOnReceiveMeasurement is defined in OxpLibTransports.h which matches the delegate
    // this passes the function pointer to the unmanaged Sensor class to be used when a 
    // measurement is received
    _sensor->RegisterForMeasurementCallback((fnOnReceiveMeasurement)(ip.ToPointer()));

希望有人对这个问题有一个很好的答案。我可能错过了一些愚蠢的东西。

【问题讨论】:

    标签: c++-cli marshalling unmanaged managed


    【解决方案1】:

    支持。您可以使用属性告诉 CLR 它为委托创建的 thunk 应该使用 __cdecl 调用约定。让它看起来像这样:

    using namespace System::Runtime::InteropServices;
    
    [UnmanagedFunctionPointer(CallingConvention::Cdecl)]
    delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);
    

    【讨论】:

    • 再次感谢!在不到 24 小时内两次。这比内联汇编要好得多,以消除单个 add esp, 4 语句。非常感谢。
    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多