我已经获得了第三方C / C ++库(.dll,.lib,.exp和.h),我需要在我们的C#应用程序中使用它。
ThirdPartyLibrary.h包含......
class AClass {
public:
typedef enum {
green = 7,
blue = 16
} Color;
virtual int GetData()=0;
virtual int DoWork(Color, char *)=0;
};
void * Func1(int, AClass **aClass);
在我的C ++ / CLI代码中,我已经完成了这个......
#include "ThirdPartyLibrary.h"
using namespace System;
using namespace System::Runtime::InteropServices;
namespace Wrapper {
public ref class MyBridgeClass
{
private:
AClass* pAClass;
public:
// C# code will call this method
void AMethod (int x)
{
int y = x+10;
Func1 (y, &(this->pAClass)); // <-- error!
}
}
}
我收到一个构建错误,内容为......
cannot convert parameter 2 from 'cli::interior_ptr<Type>' to 'AClass **'
with
[
Type=AClass *
]
Cannot convert a managed type to an unmanaged type
有什么想法吗?也许我需要在我的C ++ / CLI中使用#pragma manage / unmanged标签?
答案 0 :(得分:1)
您收到该错误的原因是托管内存的工作原理。
在托管类中,您已经定义了一个指针。该指针的地址是托管对象的一部分,并且可以在垃圾收集器运行时更改。这就是为什么你不能只将&pAClass
传递给方法,GC可以改变实际上的地址。
你可以采取一些措施来解决这个问题:
您可以创建一个非托管辅助类来保存AClass*
成员。如果指针需要在此方法的调用之外保持有效,或者如果你有很多非托管指针要保持,我会这样做。
struct UnmanagedHolder
{
AClass* pAClass;
};
public ref class MyBridgeClass
{
private:
// must create in constructor, delete in destructor and finalizer.
UnmanagedHolder* unmanaged;
public:
// C# code will call this method
void AMethod (int x)
{
int y = x+10;
Func1 (y, &(this->unmanaged->pAClass));
}
};
如果您只需要指针在AMethod中有效,并且在调用Func1后指针不需要保持有效,那么您可以使用pin_ptr。
void AMethod (int x)
{
int y = x+10;
pin_ptr<AClass*> pin = &(this->pAClass);
Func1 (y, pin);
}