如何在非托管C++中调用托管C#代码

我在人间做项目 2013-06-25 12:04:04
现在做到一个视频驱动二次开发的项目,视频服务平台的SDK是C#的,但是要集成到我们的平台是MFC架构的,一个是托管,一个是非托管,就牵涉到了一个非托管MFC调用托管C#的问题
网上的方法多数是将C#封装成为COM,但是我在封装的时候遇到一个问题就是,我封装的这个COM要引用到视频SDK中的很多dll,但是这些dll是没有强命名的

后来我在网上找到了给没有代码的dll强命名的方法——用指令先生成一个snk密钥文件,然后对没有强命名的dll进行反编译,然后把snk密钥植入进去,然后再重新编译成为dll,再重新引用到项目里面,这样的在编译的时候强命名的问题是没有了,可是又说我没有引用dll,可是我明明是引用了啊,如下图

纠结了好多天了,大神们求救啊!!!小弟感激不尽啊
...全文
446 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2013-07-05
  • 打赏
  • 举报
回复
你的反编译不彻底啊,你看错误信息,这些dll之间存在着相互引用,引用时使用的是未签名的dll,你现在为每个dll都签名了,自然引用的时候会出错。 你先确定是否必须对dll进行强名称后才能引用,因为我在C#里面就不需要,开启CLR支持的C++也应该不需要,我不清楚你用的什么方式在C++中引入的.NET支持,建议使用CLR支持。 如果实在无法避免强名称的限制,你可以再新建一个C#项目,将这些dll重新封装下,dll本身保持未签名状态,而新建的C#项目进行强名签名,你的C++项目引用自己的C#项目,这样就跳过了直接访问未签名dll的情况。
闲云之然 2013-07-05
  • 打赏
  • 举报
回复
引用 21 楼 ljgllxyz 的回复:
你确定不签名生成的COM可以移植到其他机器上进行使用,并且可以被非托管MFC调用???????????????
是的。只有当你需要把一个assembly部署到GAC中时,才需要强签名。
  • 打赏
  • 举报
回复
引用 13 楼 zanfeng 的回复:
视屏服务一般都不会用c#来写。用了也只是做了一些表面上的功夫。。 你可以查原设备的SDK直接来用就可以了。 如果非要用。你可以自己弄个c# dll生成com。。。在里面反射去调用相关的函数。这样最简单了。
底层还是用C++写的,但是上面被厂家封装为了C#的,给我们提供的也只有C#的SDK,底层C++人家不给
  • 打赏
  • 举报
回复
引用 12 楼 Saleayas 的回复:
你包装一下你需要用到的 C# 的 DLL。 而这个包装最简单的就是 C++/CLI。 然后你包装的这个 DLL 就可以被你的 MFC 工程使用了。
这个方法我看有一定的可行性,有demo吗?
  • 打赏
  • 举报
回复
引用 11 楼 caozhy 的回复:
甚至和什么COM也没有关系。只能说你接手的源代码本身有问题而已。
你说的对,我接受的源码没有强制命名,要是有不用这么纠结了
qldsrx 2013-07-05
  • 打赏
  • 举报
回复
修正下,我刚才用VS2012建了个MFC,启用CLR支持测试了下,完整正常,只不过有几个注意点: 一、要支持XP的话,只要在“平台工具集”里修改下,选择第二项带XP字样的选项就可以了,不过好像要打过补丁后才有。 二、直接修改CLR支持后,需要先点击“应用”按钮,然后才能到“通用属性”里面添加.NET程序集,而且那里面一开始是空的,为了程序正常使用,至少要添加System.dll和System.Windows.Forms这两个程序集。
qldsrx 2013-07-05
  • 打赏
  • 举报
回复
非托管MFC是可以调用托管C#的dll的,只要配置CLR支持,当然你的Visual Studio的版本不能太低,最好是VS2010,VS2012编译的exe文件要改设置才能在XP下面运行,因此VS2010是最好的开发MFC的版本。 要启用CLR支持,你只要对项目点击右键“属性”,在常规里找到“公共语言运行时支持”,选择第二项(默认第一项,不支持),之后只要在“通用属性”里面把必要的.NET使用的DLL添加进去,就可以在MFC下面完美使用所有.NET下面的方法。当然,CLR的语法你必须先学会使用。
  • 打赏
  • 举报
回复
引用 19 楼 pkudzy 的回复:
楼主,用C#开发的COM-visible的assembly是不需要强签名的,所以你不需要给那些SDK里的DLL签名。 如何制作COM-visible的assembly,请参考我的博客:http://blog.csdn.net/pkudzy/article/details/9199925 最后部署COM-Visible的assembly时,可以用.net framework提供的RegAsm.exe方法。另外,可以用TlbImp.exe来为COM-Visible的assembly生成tlb文件,那样就可以在C++的代码里import这个tlb文件了。
你确定不签名生成的COM可以移植到其他机器上进行使用,并且可以被非托管MFC调用???????????????
  • 打赏
  • 举报
回复
引用 18 楼 qldsrx 的回复:
你的反编译不彻底啊,你看错误信息,这些dll之间存在着相互引用,引用时使用的是未签名的dll,你现在为每个dll都签名了,自然引用的时候会出错。 你先确定是否必须对dll进行强名称后才能引用,因为我在C#里面就不需要,开启CLR支持的C++也应该不需要,我不清楚你用的什么方式在C++中引入的.NET支持,建议使用CLR支持。 如果实在无法避免强名称的限制,你可以再新建一个C#项目,将这些dll重新封装下,dll本身保持未签名状态,而新建的C#项目进行强名签名,你的C++项目引用自己的C#项目,这样就跳过了直接访问未签名dll的情况。
我自己新建的C#的dll是可以进行签名,但是这样的话MFC没法来调用C#的dll啊,因为是非托管MFC调用托管C#的dll,所以才想到封装成为COM,就是在封装成为COM的时候遇到了签名的问题了
闲云之然 2013-07-05
  • 打赏
  • 举报
回复
楼主,用C#开发的COM-visible的assembly是不需要强签名的,所以你不需要给那些SDK里的DLL签名。 如何制作COM-visible的assembly,请参考我的博客:http://blog.csdn.net/pkudzy/article/details/9199925 最后部署COM-Visible的assembly时,可以用.net framework提供的RegAsm.exe方法。另外,可以用TlbImp.exe来为COM-Visible的assembly生成tlb文件,那样就可以在C++的代码里import这个tlb文件了。
threenewbee 2013-07-01
  • 打赏
  • 举报
回复
没有你说的那么复杂。 产生一个com对象简单到只要3步,第一步是用comvisible标识类,第二步是在编译选项里面打开“对com可见”,第三步是编译后用regasm注册。 至于签名,那是可选的。
Saleayas 2013-07-01
  • 打赏
  • 举报
回复
创建一个托管的 C++ 的 DLL。 在这个 DLL 里面到处本地的 API,并且在这个 DLL 使用 C# 的 DLL 导出方法。
tcmakebest 2013-07-01
  • 打赏
  • 举报
回复
能不能尝试用命令行方式的调用啊?
足球中国 2013-07-01
  • 打赏
  • 举报
回复
视屏服务一般都不会用c#来写。用了也只是做了一些表面上的功夫。。 你可以查原设备的SDK直接来用就可以了。 如果非要用。你可以自己弄个c# dll生成com。。。在里面反射去调用相关的函数。这样最简单了。
Saleayas 2013-07-01
  • 打赏
  • 举报
回复
你包装一下你需要用到的 C# 的 DLL。 而这个包装最简单的就是 C++/CLI。 然后你包装的这个 DLL 就可以被你的 MFC 工程使用了。
threenewbee 2013-07-01
  • 打赏
  • 举报
回复
甚至和什么COM也没有关系。只能说你接手的源代码本身有问题而已。
threenewbee 2013-07-01
  • 打赏
  • 举报
回复
引用 8 楼 ljgllxyz 的回复:
[quote=引用 6 楼 caozhy 的回复:] 没有你说的那么复杂。 产生一个com对象简单到只要3步,第一步是用comvisible标识类,第二步是在编译选项里面打开“对com可见”,第三步是编译后用regasm注册。 至于签名,那是可选的。
我不知道你有没有具体的操作过,你说的这些我都知道,我也是这么照着做的,可问题就是我要生成的那个COM还引用了其他的dll,而被引用的dll没有被强命名,所以才会引出这么多的问题的,就是说直接就是C#的COM的编译都不能成功,去掉COM可见编译为普通的C#的dll是完全没有问题的[/quote] 你编译不了和C++调用有什么关系。
  • 打赏
  • 举报
回复
引用 7 楼 Saleayas 的回复:
创建一个托管的 C++ 的 DLL。 在这个 DLL 里面到处本地的 API,并且在这个 DLL 使用 C# 的 DLL 导出方法。
调用的这端是一个已经做好的平台,是非托管的,不能改啊,要是能改这问题不用这么纠结了
  • 打赏
  • 举报
回复
引用 6 楼 caozhy 的回复:
没有你说的那么复杂。 产生一个com对象简单到只要3步,第一步是用comvisible标识类,第二步是在编译选项里面打开“对com可见”,第三步是编译后用regasm注册。 至于签名,那是可选的。
我不知道你有没有具体的操作过,你说的这些我都知道,我也是这么照着做的,可问题就是我要生成的那个COM还引用了其他的dll,而被引用的dll没有被强命名,所以才会引出这么多的问题的,就是说直接就是C#的COM的编译都不能成功,去掉COM可见编译为普通的C#的dll是完全没有问题的
  • 打赏
  • 举报
回复
引用 3 楼 tangyanzhi1111 的回复:
 非托管c++调用C#貌似不可能?即使是可以也要自写中间调用过程。那个有高度。  微软VS提供了托管的C++,你可以尝试调用下。
我要是能用托管的C++就不用这么纠结了啊。。。 托管的C++肯定是能够调用C#的
加载更多回复(3)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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