我正在创建一个依赖于众多C++静态库的C++/CLI包装器DLL.一些函数调用期望传入非托管指针.如何正确传递它们?
此外,其他函数期望"this pointer"作为void*传入.传递"这个"的正确方法是什么?
这是我的班级定义......
public ref class RTPClient { public: RTPClient(); ~RTPClient(); bool Connect(); void Disconnect(); private: CIsmaClient* mClient; };
这是我在使用指针的用法...
RTPClient::RTPClient(): mClient(NULL) { CIsmaClient::Create(&mClient, NULL, &AllocBuffer, &GetDataPointer, this); }
&mClient和"this"的使用导致以下编译器错误... 1>.\ VBLoadSimulatorDll.cpp(40):错误C2664:'CIsmaClient :: Create':无法将参数1从'cli :: interior_ptr'转换为' CIsmaClient**'1> 1> [1> Type = CIsmaClient*1>]
1>.\ VBLoadSimulatorDll.cpp(40):错误C2664:'CIsmaClient :: Create':无法将参数5从'VBLoadSimulator :: RTPClient ^ const'转换为'VOID*'
如果要将指针传递给托管类,则很容易将^引用转换为指针但是必须固定托管对象,以便GC不会在内存中移动它(从而使指针无效)
使用pin_ptr这很简单
但是,您的代码正在做两件不起作用的事情
RTPClient::RTPClient(): mClient(NULL) { CIsmaClient::Create( &mClient, // 1 NULL, &AllocBuffer, &GetDataPointer, this); //2 }
1)您正在尝试获取托管堆上的某些内容的地址(指向mClient 的指针的位置在托管堆上.
因此它可以在内存中移动,因此编译器供应商内部指针(其值在GC操作上保持).这需要固定,这只有在Create函数不希望在它的作用域结束后使用指针时才会起作用(如果它在其他任何地方传递它以存储它将导致错误).
2)你传递一个句柄(滑稽的帽子符号)而不是指针.(阅读关于这些的维基百科部分,他们是一个很好的概述)这不是(也不能)被非托管代码理解.
我在这个上下文中想到这个参数的唯一原因是作为传递给后续函数回调的显式状态变量(如果我错了,请纠正我).在这种情况下,'this'永远不会正常工作,因为一旦pin_ptr超出范围,这可以在内存中移动.
考虑到这一点,这是一个(部分)纠正的实现,明确了可以修复和不修复的内容.
RTPClient::RTPClient(): mClient(NULL) { // make it clear you want the address of the instance variable pin_ptrpinnedClient = &this->mClient; CIsmaClient::Create( pinnedClient, // fixed NULL, &AllocBuffer, &GetDataPointer, x /* pass something else in */); //2 }
如果您提供有关最后一个参数用途的更多信息,我可以建议可能的解决方案