【发布时间】:2016-09-20 16:33:45
【问题描述】:
我不得不在 C# 库中公开一些方法,以便可以从用 C++ (VC++ 6.0) 编写的外部程序中使用它们。因此,我创建了一个混合程序集,到目前为止它工作得很好,但是我在使用返回 .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 类的最佳解决方案是什么,这样就不需要从 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++ 代码都是非常经典的 C++ 代码风格,甚至没有使用stdlib。
【问题讨论】:
-
我认为你必须先序列化数组然后再反序列化
-
@pho3nix 你是对的。至少如果您忽略所有 C++/CLI 功能并且不知道该语言提供了什么。否则你完全是在做不必要的事情。很棒的编程。
-
你不能使用 std::vector,编译器太老了。出于同样的原因,内存管理也是一个问题,因此使用 new 分配数组也是不可能的。使用 LocalAlloc() 或 SafeArrayCreate() 到达某个地方。
-
是的,对于曝光部分忘记 C++ - 您的导出需要坚持标准 C 级函数导出,或者您“一路”(在 .NET 方面很容易)并制作COM 对象... COM 可以追溯到很久以前。并且 COM 支持从 .NET 导出 - 但是:您更需要知道您在 COM 中做什么......
-
谢谢@TomTom ...是的 COM 是我想到的另一种方式,即使我担心客户对 COM / .tlb 等一无所知... 2016 年仍在使用 VC++ 6.0 :/ .. . 我一直在努力提供一个简单的 .exe,结果存储在文件而不是 API 中,但我不在那些决定如此疯狂/无用/愚蠢/耗时的向后支持的人的论文中;)跨度>
标签: c# c++-cli marshalling mixed-mode