简体   繁体   English

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

[英]Pass C# array of object to C++/CLI

I'm force to expose some methods in a C# library so that they can be used from an external program written in C++ (VC++ 6.0). 我被迫在C#库中公开一些方法,以便可以从用C ++(VC ++ 6.0)编写的外部程序中使用它们。 I thus created a mixed assembly which works quite ok so far but I have some troubles with a method that returns an array of .NET objects. 因此,我创建了一个混合程序集,到目前为止,该程序集还可以正常运行,但是我对返回一个.NET对象数组的方法有一些麻烦。

The .NET signature of the method is: 该方法的.NET签名为:

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

Where Results itself is: Results本身是:

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

To provide entry point from C++, I started to write a C++/CLI wrapper method like this: 为了提供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;
}

but I must admit I'm a bit lost, this is very long time I haven't wrote a single line of C++ and very long time I haven't deal with by hand memory management... 但是我必须承认我有点迷路,这很长一段时间我还没有写过一行C ++,而且很长一段时间我还没有手动处理内存管理...

What is the best solution to create ResultsWrapper class so that there will be no much need to care for memory management from C++ side. 创建ResultsWrapper类的最佳解决方案是什么,这样就不再需要从C ++端开始关心内存管理。 Maybe something like the following ? 也许像下面这样?

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; 
}

NB: I don't think team on VC++ 6.0 side are aware of boost library or share_ptr types (and I'm not very knowledgable about them either). 注意:我认为VC ++ 6.0方面的团队并不了解Boost库或share_ptr类型(我也不十分了解它们)。 All C++ code is very classic C++ code style, not even using stdlib . 所有C ++代码都是非常经典的C ++代码样式,甚至没有使用stdlib

I could not pass safely/easily STL types across dll boundaries so I get back to old char** , and manual allocation/deallocation and It Just Worked... 我无法跨DLL边界安全/轻松地传递STL类型,所以我回到了旧char** ,以及手动分配/取消分配和它就可以了...

IJW for a while only ... then I tried to check for when throwing exception from .NET back to the calling C++ application and then patatra ... need conversion to native exceptions ... that again cannot safely cross dll boundaries ... IJW仅持续了一段时间...然后我尝试检查将.NET中的异常引发回调用C ++应用程序然后进行patatra时的情况...需要转换为本机异常...再次无法安全地跨越DLL边界...

Mixed mode assemblies sounded appealing to go from .NET to native but was an IJS experience in my case... I give up and will go through COM instead. 从.NET转到本机,混合模式程序集听起来很吸引人,但就我而言,这是一种IJS体验……我放弃了,而是通过COM。

In C++/CLI I started to write a wrapper method like this: 在C ++ / CLI中,我开始编写这样的包装器方法:

No, you did not 不,你没有

public Results[] Measure(String model, String identifier); 公共结果[]措施(字符串模型,字符串标识符);

has no resemblance in 与...没有相似之处

std::vector Measure(char* model, char* identifier) std :: vector Measure(char *模型,char *标识符)

None. 没有。

There is no marshalling required in a C++/CLI reference class. C ++ / CLI参考类中不需要编组。 Use String^ as pointer to string (instead of char*) and use array<ResultsWrapper>^ as pointer to a managed array. 使用String ^作为指向字符串的指针(而不是char *),并使用array<ResultsWrapper>^作为指向托管数组的指针。

There is no need to use a wrapper at all. 根本不需要使用包装器。 Declare a class as managed reference (ref class) and you can call it from the .NET side because it is a .NET class. 将一个类声明为托管引用(ref类),因为它是.NET类,所以可以从.NET端调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM