坚持调用约定从非托管C ++调用Managed CLI方法

时间:2013-04-28 16:00:15

标签: c++-cli marshalling unmanaged managed

我试图从非托管代码中调用托管方法。但是,托管代码要求我使用'(__ clrcall)调用约定,而我的非托管C ++代码拒绝让我使用__clrcall调用约定而不使用/ clr选项。我不相信我想这样做,因为非托管项目不是我可以改为托管的。

我已经在CodeGuru和MSDN上看到了在托管端构建所有这些委托和函数指针编组,但是除非我使用不能成为a成员的__stdcall约定调用静态函数,否则此错误仍然会弹出ref class。该方法需要是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()));

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

1 个答案:

答案 0 :(得分:7)

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

using namespace System::Runtime::InteropServices;

[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);