C ++ / CLI:将C ++类ptr传递给非托管方法

时间:2013-05-01 15:16:42

标签: c++-cli pointers

我已经获得了第三方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标签?

1 个答案:

答案 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);
}