将 C# 对象数组传递给 C++/CLI

Pass C# array of object to C++/CLI

我不得不在 C# 库中公开一些方法,以便可以从用 C++ (VC++ 6.0) 编写的外部程序中使用它们。因此,我创建了一个混合程序集,到目前为止它工作得很好,但是我在使用 returns .NET 对象数组的方法时遇到了一些麻烦。

方法的.NET签名是:

public Results[] Measure(String model, String identifier);

其中 Results 本身是:

public class Results
{
    public String[] ElementType;
    public bool[] HasError;
}

为了从 C++ 提供入口点,我开始编写 C++/CLI 包装器方法,如下所示:

std::vector<ResultsWrapper> Measure(char* model, char* identifier)
{
    // Call .NET code
    String^ gcmodel = gcnew System::String(model);
    String^ gcidentifier = gcnew System::String(identifier);
    cli::array<Results^>^ gcres = myNetInstance->Measure(gcmodel, gcidentifier);

    // Convert results to C++ vector
    std::vector<ResultsWrapper> ret;
    for (int ki = 0; ki < res->Length; ki++)
    {
        ResultsWrapper r = ResultsWrapper(res[ki]->...., );
        ret.push_back(r);
    }

    return ret;
}

但我必须承认我有点迷茫,这是很长一段时间我没有写过一行 C++ 也很长时间没有处理 手动 内存管理...

创建 ResultsWrapper class 的最佳解决方案是什么,这样就无需过多关心 C++ 端的内存管理。也许像下面这样?

class ResultsWrapper
{
   public:
      ResultsWrapper(vector<std::String> elementType, vector<bool> hasError)
      {
         this.ElementType = elementType;
         this.HasError = hasError;
      }

   public:
     vector<std:String> ElementType;
     vector<bool> HasError; 
}

注意:我认为 VC++ 6.0 方面的团队不了解 boost 库或 share_ptr 类型(而且我对它们也不是很了解)。所有的 C++ 代码都是非常 classic C++ 代码风格,甚至没有使用 stdlib.

In C++/CLI I started to write a wrapper method like this:

不,你没有

public Results[] Measure(String model, String identifier);

没有相似之处

std::vector Measure(char* model, char* identifier)

None.

C++/CLI 参考中不需要编组 class。使用 String^ 作为指向字符串的指针(而不是 char*)并使用 array<ResultsWrapper>^ 作为指向托管数组的指针。

根本不需要使用包装器。将 class 声明为托管引用 (ref class),您可以从 .NET 端调用它,因为它是 .NET class.

我无法跨 dll 边界传递 safely/easily STL 类型,所以我回到旧的 char** 和手册 allocation/deallocation 并且它只是工作...

IJW 只用了一段时间...然后我尝试检查何时将异常从 .NET 抛回给调用 C++ 应用程序然后 patatra...需要转换为本机异常...再次无法安全地交叉dll 边界 ...

从 .NET 到本机,混合模式程序集听起来很有吸引力,但在我的情况下是一种 IJS 体验......我放弃了,将通过 COM 来代替。