【问题标题】:C#/C++ pInvoke tipsC#/C++ pInvoke 提示
【发布时间】:2010-10-26 23:13:48
【问题描述】:

从 C#.NET CF 修改要与 pInvoke 一起使用的 C++ 程序的最佳方法是什么?

我有一个大量使用 STL 的大型 C++ 代码库。即迭代器、容器类和标准字符串。

除此之外,许多轻量级类都是按值传递的。

我想在这个代码库的基础上为 Windows 移动触摸设备构建一个 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#。

【问题讨论】:

    标签: c# c++ .net pinvoke windows-mobile


    【解决方案1】:

    我个人会说这是值得的,但我同意另一个帖子,这并不容易。

    可能的方法可能是:

    1. 围绕 C++ 的 C 接口并作为 DLL 公开。
    2. COM 对象(虽然 WM 不支持 COM 服务器,因此您不得不使用进程内服务器,基本上是 DLL COM 实现)。这将为您提供更面向对象的界面。
    3. 后台进程公开某种 API。您可以使用“CE 服务”模式或提出自己的 API。

    一切皆有可能,各有利弊。无论做什么,都不能在界面中使用 STL 类型。您已简化为易于在进程之间编组的简单基本类型。既然你在谈论C#,那么COM可能会因为你可以暴露OO接口。

    我建议尽量保持两者之间的界面尽可能简单。

    【讨论】:

    • 感谢您的提示,尽管我不确定选项 3 的含义。我同意我的接口太宽泛,我应该让 C# 和 C++ 之间的桥梁尽可能小。目前甚至返回迭代器引用,每次它们增加或取消引用自己时都需要调用 pinvoke ... eek.
    • 选项 3:您创建一个在后台运行的应用程序 (exe)(它可以一直运行或由 gui 前端启动和停止)并与您的前端(GUI ) 应用程序使用您编写的某种 API,例如使用共享内存或消息队列或任何您喜欢的东西。排序类似于 Win32 服务。您的后台应用程序通常会在某种事件循环中接收命令并处理它们。
    【解决方案2】:

    你想做的事一点也不简单。如果您真的想要这样做,最好的办法是创建一些干净的 C 接口,这些接口包含所有 C++ 和 STL 内容,并传递可以很好地从 .net 传递到 C 的结构。根据您拥有的代码库有多大,这可能是一项非常困难的任务。

    对不起。

    【讨论】:

    • 感谢您的建议,我认为是这种情况,但在走这条路之前想确定一下。
    【解决方案3】:

    也许您应该编写一个 com 包装器,然后使用 .net 工具自动为您创建 c# 程序集?

    【讨论】:

    • COM 存在于 windows mobile 中
    • 有,但 CF 中的 COM 互操作不容易
    【解决方案4】:

    SWIG 没有为您创建 C++ 的 C 风格包装器吗?就像处理复杂 c++ 的所有非基础知识一样?如果我错了,请纠正我,因为我处于类似的情况,我想包装一个暴露在 dll 中的非常大且复杂的 C++ api。我需要通过编写 C 风格来避免重整和非基本数据类型包装器在 Pinvoking 之前公开所有内容,鉴于 api 的大小以及类型和原型的复杂性,如果没有自动化工具是不可行的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多