gpt4 book ai didi

c++-cli - 坚持从非托管 C++ 调用约定调用托管 CLI 方法

转载 作者:行者123 更新时间:2023-12-02 07:36:14 25 4
gpt4 key购买 nike

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

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

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

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

这是我的委托(delegate)定义(所有这些都属于一个 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()));

希望有人能很好地回答这个问题。我可能遗漏了一些愚蠢的东西。

最佳答案

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

using namespace System::Runtime::InteropServices;

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

关于c++-cli - 坚持从非托管 C++ 调用约定调用托管 CLI 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16264734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com