分享 N种方法使用C++调用C#.NET库

sknice 2015-04-09 03:32:10
加精
为了减少篇幅,此文不描述何种场景下需要使用C++调用C#/VB等托管代码,而直接给出三种常规方法和一些变通方法以供参考。

常规方法1:COM

使用C#把托管类注册成COM,用regasm.exe注册output assembly,然后用C++像调用COM一样调用assembly里面的type。

优点:编写代码简单,调用方便

缺点:需要注册output,发布不够简单

参考:http://www.codeproject.com/KB/cs/ManagedCOM.aspx

常规方法2:CLR

C#常规编写类,生产assembly,C++使用CLR编译既可直接引用托管类。

优点:编写代码简单,调用方便

缺点:需要了解C++ CLR语法(既不像C++,又不像C#,总之很奇怪)

参考:http://www.codeproject.com/KB/mcpp/cppcliintro01.aspx ,http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx

常规方法3(推荐):API

C#常规编写类,生产assembly,C++使用SDK提供的CLR非托管接口(CLRCreateInstance)进行调用。

优点:传统C#编程,传统C++编程

缺点:暂时还没发现

参考:http://nport.codeplex.com/SourceControl/changeset/view/45681#903468 ,http://msdn.microsoft.com/en-us/library/dd537633.aspx

变通方法:

1. 使用C#/VB包装现有托管类,注册成Windows服务,暴露SOAP web service。VC2005可以使用非托管代码添加引用Web service。

2. 使用C#/VB包装现有托管类,注册成Windows服务。C++利用Windows message和服务通讯。

3. 使用C#/VB包装现有托管类,注册成Windows服务。C++利用Windows共享内存和服务通讯。

其实利用双进程通讯的方法,可以演变出各种各样调用的思路。聪明的你可以充分发挥想象力,写出自己独有的调用模式。
...全文
10892 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
clwk 2018-12-12
  • 打赏
  • 举报
回复
顶一下
hsaesj 2015-04-24
  • 打赏
  • 举报
回复
bogeda1501 2015-04-22
  • 打赏
  • 举报
回复
感谢分享~,还不错 赞一个
fier1 2015-04-20
  • 打赏
  • 举报
回复
跨语言的调用应当非常普遍吧,例如所有语言调用系统API都是在跨语言, 下面是AAuto里调用C#程序集的一个例子,跨个语言也没那么麻烦:
import dotNet; 
import console;

var clr,err = dotNet.clr(); 
var appDomain = clr.createAppDomain();

//直接指定文件路径,资源文件路径,或内存数据加载程序集
var Interop = appDomain.loadFile($"~/lib/dotNet/.res/AAuto.InteropServices.dll");
var csProxy = Interop.createInstance("AAuto.InteropServices.CSharp");
 
//加载程序集并创建实例,支持添加多个构造参数
var CSSimpleObject = appDomain.createInstance( "CSNET2ClassLibrary","CSNET2ClassLibrary.CSSimpleObject");
console.log( "创建实例并获取值",CSSimpleObject.FloatProperty )

//指定文件路径加载程序集并创建实例
var CSSimpleObject = appDomain.createInstanceFrom( "/CSNET2ClassLibrary.dll","CSNET2ClassLibrary.CSSimpleObject");
console.log( "创建实例并获取值",CSSimpleObject.FloatProperty )

appDomain.unload();
console.pause()
bigbaldy 2015-04-20
  • 打赏
  • 举报
回复
可惜不能保证性能
laowang2 2015-04-19
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
“放之四海而皆准”的方法: 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
正解!不过会有点慢
赵4老师 2015-04-18
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
ArthurKingYs 2015-04-18
  • 打赏
  • 举报
回复
学习 学习 求实例
赵4老师 2015-04-17
  • 打赏
  • 举报
回复
“放之四海而皆准”的方法: 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
程序员鼓励师 2015-04-17
  • 打赏
  • 举报
回复
shiter 2015-04-16
  • 打赏
  • 举报
回复
最好有点小例子学习一下
clever101 2015-04-16
  • 打赏
  • 举报
回复
强大,学习!
Sandrer 2015-04-15
  • 打赏
  • 举报
回复
我知道一个需要用到的场合: SQL2008 可以使用 .net 的dll来完成一些很强大的扩展功能
Eleven 2015-04-15
  • 打赏
  • 举报
回复
感谢分享~
coolksj 2015-04-15
  • 打赏
  • 举报
回复
顶一下,嘎嘎,接分

1,658

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 非技术类
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧