C#/C++ pInvoke提示
修改 C++ 程序以与 C#.NET CF 中的 pInvoke 一起使用的最佳方法是什么?
我有一个大型的 C++ 代码库,它广泛使用了 STL。 即迭代器、容器类和标准字符串。
除此之外,许多轻量级类通过值传递。
我想在此代码库之上为 Windows Mobile 触摸设备构建一个 C# gui。
这值得么?
我已经成功地获得了一些使用 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#。
Whats the best way to go about modifying a C++ program to be used with pInvoke from C#.NET CF?
I have a large C++ codebase which makes extensive use of STL. Namely iterators, container classes, and standard strings.
On top of this many lightweight classes are passed around by value.
I want to build a C# gui ontop of this codebase for windows mobile touch devices.
Is it worth it?
I have managed to get some examples working using pInvoke to call C++ code from C#.NET, but writing wrappers for every access point and for all the STL return types seems very daunting and ugly. Is there another way or am I somewhat stuffed?
BTW. Managed C++ is not an option becuase its not supported in any form by .NET CF.
--edit:
I have one specific question in regards to pinvoke.
Suppose you had a function returning a C++ string by value
std::string foo () {
return std::string ("Hi");
}
I understand that its not possible to call this function from C# using pinvoke because there is no way to marshall the STL string, but my problem is that I cannot even write a wrapper without allocating a new array becuase the std::string returned is not on the heap.
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.
}
So my problem is, how to wrap foo into a pInvoke suitable format without needing to re-allocate the whole string.
char* foo2 () {
std::string f = foo();
char* waste = new char[f.length()+1];
strcpy (waste, f.c_str());
return f;
}
The thought of doing the above for every point at which I need to return a std::string is enough to make me give up trying to use C#.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我个人认为这是值得的,但我同意另一篇文章的观点,即这并不容易。
可能的方法可能是:
一切皆有可能,各有利弊。 无论您做什么,都不能在界面中使用 STL 类型。 您已简化为易于在进程之间编组的简单基本类型。 既然你谈论的是 C#,那么 COM 可能会消失,因为你可以公开 OO 接口。
我建议尝试使两者之间的接口尽可能简单。
I would personally say it's worth it, but I agree with the other post that it's not easy.
Possible approaches may be:
All are possible and have there pros and cons. Whatever you do, you can't use STL types in the interface. You have reduced to simple basic types that are easy to marshal between the processes. Since your talking about C#, then COM may be go as you can expose OO interface.
I would recommend trying to keep the interface between the two as simple as possible.
你想做的事一点也不容易。 如果您真的想要这样做,那么最好的选择是创建一些干净的 C 接口,其中包含所有 C++ 和 STL 内容,并传递可以很好地从 .net 传递到 C 的结构。 根据您拥有的代码库的大小,这可能是一项非常困难的任务。
对不起。
What you want to do is not easy at all. If you really wanted to do it, your best bet is to create some clean, C interfaces that wrap all of the C++ and STL stuff and pass around structures that can pass from .net to C nicely. Depending on how big of a codebase you have, it can be a very difficult task.
Sorry.
也许您应该编写一个 com 包装器,然后使用 .net 工具自动为您创建 C# 程序集?
maybe you should write a com wrapper and then use .net tool that will automatically create c# assembly for you?
SWIG 没有为您创建 C++ 的 C 风格包装器吗? 就像处理复杂的 C++ 的所有非基础知识一样? 如果我错了,请纠正我,因为我处于类似的情况,我想包装一个在 dll 中公开的非常大且复杂的 C++ api..我需要通过编写 C 风格来避免损坏和非基本数据类型包装器在 Pinvoking 之前公开所有内容,考虑到 api 的大小以及类型和原型的复杂性,如果没有自动化工具,这是不可行的。
doesnt SWIG create a C-style wrapper for C++ for you? Like handing all the non-basics of complex c++ ? Correct me if i'm wrong because I'm in a similar situation, I want to wrap a very large and complex C++ api exposed in a dll..i need to avoid mangling and the non basic data types by writing a C-style wrapper to expose all the stuff before Pinvoking that and it is infeasible without automated tools given the size of the api and the complexity of the types and prototypes.