Stuck on calling convention calling Managed CLI method from unmanaged C++

让人想犯罪 __ 提交于 2020-01-04 09:38:10

问题


I am trying to call a managed method from unmanaged code. However, the managed code is requiring that I use the '(__clrcall) calling convention, and my unmanaged C++ code refuses to let me use the __clrcall calling convention without using the /clr option. I don't believe I want to do that as the unmanaged project is not mine to change to managed.

I have gone through constructing all those delegates and function pointer marshaling in the managed side as I have seen on CodeGuru and MSDN but this error still pops up unless I call a static function using a __stdcall convention that cannot be a member of a ref class. The method needs to be an instance of a ref class.

The only way I have been able to get around this is to do my method call from the unmanaged code in assembly skipping the popping of the ESP register (adding 4) after the call (the call has one parameter in the argument thus the '4'). That allows me to effectively do a __clrcall. That option stinks big time.

Anybody have any ideas on how to work around this issue? It must surely be possible. I am missing some simple but vital piece of information.

Here is my delegate definition (all of these belong to a single ref class ManagedSensor):

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

Here is the instance method I want to call

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

And here is the marshaling of the ref class function to the unmanaged function done in the ref class constructor:

    // 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()));

Hope somebody has a nice answer to this issue. I am probably missing something stupid.


回答1:


That is supported. You can use an attribute to tell the CLR that the thunk it creates for the delegate should use the __cdecl calling convention. Make it look like this:

using namespace System::Runtime::InteropServices;

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


来源:https://stackoverflow.com/questions/16264734/stuck-on-calling-convention-calling-managed-cli-method-from-unmanaged-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!