[英]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.