修改 C++ 程序以与来自 C#.NET CF 的 pInvoke 一起使用的最佳方法是什么?
我有一个大型 C++ 代码库,它广泛使用了 STL。即迭代器、容器类和标准字符串。
除此之外,许多轻量级类都是按值传递的。
我想在此代码库之上为 Windows 移动触摸设备构建一个 C# 图形用户界面。
值得吗?
我已经设法获得了一些使用 pInvoke 从 C#.NET 调用 C++ 代码的示例,但是为每个访问点和所有 STL 返回类型编写包装器似乎非常令人生畏和丑陋。还有其他方法还是我有点吃饱了?
顺便说一句。托管 C++ 不是一个选项,因为 .NET CF 不以任何形式支持它。
--编辑: 我有一个关于 pinvoke 的具体问题。
假设您有一个按值返回 C++ 字符串的函数
std::string foo () {
return std::string ("Hi");
}
我知道无法使用 pinvoke 从 C# 调用此函数,因为无法编码 STL 字符串,但我的问题是我什至无法在不分配新数组的情况下编写包装器,因为 std::string返回的不在堆上。
char* foo2 () {
return foo().c_str(); //Very bad
//the returned pointer is released when the std::string falls out of scope.
//and will be invalid before the caller is able to do anything with it.
}
所以我的问题是,如何将 foo 包装成 pInvoke 合适的格式而不需要重新分配整个字符串。
char* foo2 () {
std::string f = foo();
char* waste = new char[f.length()+1];
strcpy (waste, f.c_str());
return f;
}
对我需要返回 std::string 的每个点执行上述操作的想法足以让我放弃尝试使用 C#。
最佳答案
我个人认为这是值得的,但我同意另一篇文章的观点,这并不容易。
可能的方法可能是:
- 围绕 C++ 的 C 接口(interface)并公开为 DLL。
- COM 对象(尽管 WM 不支持 COM 服务器,因此您不得不使用进程内服务器,基本上是 DLL COM 实现)。这将为您提供更面向对象的界面。
- 公开某种 API 的后台进程。您可以使用“CE 服务”模式或提供您自己的 API。
一切皆有可能,各有利弊。无论您做什么,都不能在界面中使用 STL 类型。您已简化为易于在进程之间编码的简单基本类型。既然你在谈论 C#,那么 COM 可能会消失,因为你可以公开 OO 接口(interface)。
我建议尽量保持两者之间的界面尽可能简单。
关于C#/C++ pInvoke 技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/876553/