0

我已经获得了需要在我们的 C# 应用程序中使用的第三方 C/C++ 库(.dll、.lib、.exp 和 .h)。

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 标签?

4

1 回答 1

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);
}
于 2013-05-01T15:43:59.117 回答