将 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 来代替。
我不得不在 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 来代替。