C++ cli C++/CLI:通过C++;类ptr到非托管方法
我得到了一个第三方C/C++库(.dll、.lib、.exp和.h),我需要在我们的C#应用程序中使用它 第三方图书馆.h包含C++ cli C++/CLI:通过C++;类ptr到非托管方法,c++-cli,pointers,C++ Cli,Pointers,我得到了一个第三方C/C++库(.dll、.lib、.exp和.h),我需要在我们的C#应用程序中使用它 第三方图书馆.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 **aCla
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!
}
}
}
#包括“第三方图书馆.h”
使用名称空间系统;
使用名称空间System::Runtime::InteropServices;
名称空间包装器{
公共引用类MyBridgeClass
{
私人:
AClass*pAClass;
公众:
//C代码将调用此方法
虚空法(整数x)
{
int y=x+10;
Func1(y,&(this->pAClass));//出现此错误的原因是托管内存的工作方式
在托管类中,您已经定义了一个指针。该指针的地址是托管对象的一部分,在垃圾回收器运行时可以更改。这就是为什么您不能将&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);
}
void-AMethod(int x)
{
int y=x+10;
pin_ptr pin=&(此->pAClass);
函数1(y,pin);
}
出现此错误的原因是受管内存的工作方式
在托管类中,您已经定义了一个指针。该指针的地址是托管对象的一部分,在垃圾回收器运行时可以更改。这就是为什么您不能将&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);
}
void-AMethod(int x)
{
int y=x+10;
pin_ptr pin=&(此->pAClass);
函数1(y,pin);
}
我知道固定,但我没有意识到非托管字段仍然在托管堆上分配。我在桥接类“ctor”和“if”(this->unmanaged)中添加了一个“this->unmanaged=new UnmanagedHolder()”将此->未管理字段删除到网桥类终结器。我知道钉住,但我没有意识到未管理字段仍在托管堆上分配。我将“this->unmanaged=new UnmanagedHolder()”添加到网桥类“ctor”,并将“if(this->unmanaged)删除此->未管理字段”添加到网桥类终结器。