草庐IT

C#/C++ pInvoke 技巧

coder 2024-02-21 原文

修改 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#。

最佳答案

我个人认为这是值得的,但我同意另一篇文章的观点,这并不容易。

可能的方法可能是:

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

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

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

关于C#/C++ pInvoke 技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/876553/

有关C#/C++ pInvoke 技巧的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  3. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  4. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  5. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  6. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  7. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  8. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

  9. ruby - rails 3.2.2(或 3.2.1)+ Postgresql 9.1.3 + Ubuntu 11.10 连接错误 - 2

    我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat

  10. ruby - 在 Ruby + Chef 中检查现有目录失败 - 2

    这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post

随机推荐