打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
http://www.cnblogs.com/Jianchidaodi/archive/2...

在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译。这样一来,就涉及C#托管代码与C++非托管代码互相调用,于是调查了一些资料,顺便与大家分享一下:源代码下载

一. C# 中静态调用C++动态链接

 

    1. 建立VC工程CppDemo,建立的时候选择Win32 Console(dll),选择Dll。

    2. 在DllDemo.cpp文件中添加这些代码。

Code

    3. 编译工程。

    4. 建立新的C#工程,选择Console应用程序,建立测试程序InteropDemo
    5. 在Program.cs中添加引用:using System.Runtime.InteropServices;

    6. 在pulic class Program添加如下代码: 

 

Code

   好了,现在您可以测试Add程序了,是不是可以在C# 中调用C++动态链接了,当然这是静态调用,需要将CppDemo编译生成的Dll放在DllDemo程序的Bin目录下

二. C# 中动态调用C++动态链接

 在第一节中,讲了静态调用C++动态链接,由于Dll路径的限制,使用的不是很方便,C#中我们经常通过配置动态的调用托管Dll,例如常用的一些设计模式:Abstract Factory, Provider, Strategy模式等等,那么是不是也可以这样动态调用C++动态链接呢?只要您还记得在C++中,通过LoadLibrary, GetProcess, FreeLibrary这几个函数是可以动态调用动态链接的(它们包含在kernel32.dll中),那么问题迎刃而解了,下面我们一步一步实验

    1.  将kernel32中的几个方法封装成本地调用类NativeMethod

Code


    2. 使用NativeMethod类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。原因很简单,C#中已经不能使用指针了,如下         
            int hModule = NativeMethod.LoadLibrary(@"c:"CppDemo.dll");

            IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

详细请参见代码

Code


通过如上两个例子,我们可以在C#中动态或者静态的调用C++写的代码了,找了半天好像没看到可以上传源代码的地方,不过代码比较清楚了,需要的朋友可以留个邮箱,源代码下载


 

 

绿色通道: 好文要顶 关注我 收藏该文与我联系
3
0
(请您对文章做出评价)
博主上一篇:【装载】宋鸿兵:美国国债是史上最大骗局 中日是最大输家
博主下一篇:C#托管代码与C++非托管代码互相调用二(C++调用C#代码)
首页上一篇:并行编程的基础
首页下一篇:愤怒之余的反省
posted on 2009-03-09 20:30 Jianchidaodi 阅读(5807) 评论(27) 编辑 收藏

FeedBack:
#1楼
2009-03-09 20:50 | pgg[未注册用户]
老兄,问一下,C#调用C++动态库会不会有效率问题?
  
#2楼[楼主]
2009-03-09 21:00 | Jianchidaodi  
互相调用肯定是有一定的性能损耗,所以如果非必要可以不这么做。我们项目这么做的目的主要是希望核心算法方面希望保密,不被反编译,由于现在一般硬件配置都比较高,所以这种性能损耗是可以接受的
支持(0)反对(0)
  
#3楼
2009-03-09 21:20 | Hr  
要想保证核心算法的安全性靠这种方式还是欠妥,动态库很容易被od动态调试,要想保证核心算法的保密,我所知道的是可以尝试使用成熟点的虚拟机加密技术,有关.net下面的安全性反调试反汇编所涉及的东西很多,也很深,有兴趣可以上看雪网站去参考一下高手的意见.
支持(0)反对(0)
  
#4楼[楼主]
2009-03-09 21:25 | Jianchidaodi  
虚拟机加密技术,这个以前还是没有尝试过,非常感谢楼上这位朋友
支持(0)反对(0)
  
#5楼[楼主]
2009-03-09 22:15 | Jianchidaodi  
这种方法核心的代码需要用C++写,成本比较高,但是苦于目前还没找到好的解决方法,有做个的朋友多提供写思路哦,非常感谢
支持(0)反对(0)
  
#6楼
2009-03-09 22:15 | Clark Zheng  
不错,觉得以后肯定会用上,先学习和收藏了
PS:上传文件在后台管理->文件,和随笔是平行的Tab页
支持(0)反对(0)
  
#7楼[楼主]
2009-03-09 22:18 | Jianchidaodi  
博客园账号早开了,但是一直没时间写,谢谢楼上这位朋友,下次能找到上传附件的地方了
支持(0)反对(0)
  
#8楼[楼主]
2009-03-09 22:29 | Jianchidaodi  
.net一般的办法保护办法就这几种:标识符重命名、控制流模糊化、字符串加密,是在一定程度上可以保护不被反编译,但是项目牵涉到版权保护,所以想做的更好一点
支持(0)反对(0)
  
#9楼
2009-03-09 23:07 | trueneter[未注册用户]
正好需要这个,请发一份到我的邮箱,感谢!
  
#10楼[楼主]
2009-03-09 23:58 | Jianchidaodi  
楼上这位朋友,代码已经发到你邮箱去了,另外源代码链接直接加到原文中了,需要的朋友直接下载就可以了
支持(0)反对(0)
  
#11楼
2009-03-10 08:55 | trueneter[未注册用户]
感谢BZ!
  
#12楼
2009-03-10 09:47 | ZOK[未注册用户]
又是麻烦的互操作,唉。。。。。。。。
  
#13楼
2009-03-10 09:51 | winzheng  
c++ 调用C#的代码呢? 期待中...
支持(0)反对(0)
  
#14楼[楼主]
2009-03-10 10:27 | Jianchidaodi  
第二部分C++ 调用C#的代码稍后放上来,后面还有一些关于C#代码安全的资料到时候也一起分享一下
支持(0)反对(0)
  
#15楼
2009-03-10 13:48 | 大石头  
有一个软件的插件,只支持Native DLL的插件,提供了头文件和静态链接库。
请问,有什么好办法能够实现使用C#来编写插件?

我目前的做法是用C++写一个DLL,给C#提供接口,C#编译成COM,DLL调用这个COM。但是,静态链接库里面,几乎都是C++的类,不是简单的函数,而C#要调用Native DLL中的类,就太痛苦了。
支持(0)反对(0)
  
#16楼
2009-03-10 13:51 | 大石头  
等……
支持(0)反对(0)
  
#17楼[楼主]
2009-03-10 14:13 | Jianchidaodi  
如果只支持Native DLL的插件,而又希望使用C#,那就只能C#编译成COM,然后DLL调用这个COM。
当然可以考虑直接使用C++
支持(0)反对(0)
  
#18楼[楼主]
2009-03-10 14:20 | Jianchidaodi  
实际上目前我的项目中,也是C++与C#混合调用,确实操作有点麻烦,当然与楼上这位朋友不同,我这么做的最初目的是为了核心代码不被反编译才有意这么做的,4楼那位朋友提到的虚拟机加密技术目前也在研究中
支持(0)反对(0)
  
#19楼
2009-03-10 22:14 | 大石头  
C++调用C#实现的COM,这个我做好了,也能用。
但是C#中肯定要调用一些插件公开的接口函数的,而我只能通过C++一点点的暴露出来,也就是你前面所提到的C#调用Native DLL的方式。
我的C++功底太差,不知道如何把C++中的类暴露给C#
支持(0)反对(0)
  
#20楼[楼主]
2009-03-11 08:31 | Jianchidaodi  
我C++倒是学习了很久,曾经工作的时候用过一段时间的C++,但是也不是蛮好,最近在研究Sqlite & Sqlite .Net的时候受到启发蛮大的,建议你也可以研究下,其中Sqlite是C++写的,Sqlite .Net是用C#给Sqlite写的驱动
支持(0)反对(0)
  
#21楼
2010-12-24 15:02 | hugangyong  
你的思维逻辑很强,
第一:很缜密
第二:很有条理
第三:很能融汇贯通
第四:简单清晰
第五:我喜欢
支持(0)反对(0)
  
#22楼
2010-12-24 15:14 | hugangyong  
我讨论互操作
互操作的问题我也遇到一个项目
新功能的核心部分选择用的是c#(集成在老产品的c++架构上)
原因:
1.缺c++人手,c#人手充足
2.客户要求很急迫
c#和c++之间就有个交互的问题
方式很多种
其中,楼主给的c#调用c++的dll只是其中一种,这种方式的弊端是显而易见的,指针,结构体,对象,等比较复杂的数据类型在作为参数传递的时候,很难做好映射,当然你考虑到了静态和动态的调用方式,总结得非常好,21楼的时候就说了
其实我们可以反过来
c++中调用c#dll
我希望楼主是否也能帮我们总结出来
还有调用的方式是com作为中间平台,这样是最优的,数据类型的映射给我们屏蔽,当然这个也是双向的

支持(0)反对(0)
  
#23楼
2010-12-24 15:19 | 大石头  
@hugangyong
C++调用C#这个我熟悉,哈哈!

就是用C++/CLI重新编译你的东西,然后调用C#就是了。
更复杂的,你可以看看我写的IDACSharp。
IDA是一个有名的逆向分析软件,接口是C++的,我用C++/CLI包装了,再暴露给C#。启动插件的时候,IDA调用我的插件,我的C++/CLI插件再调用C#插件
支持(0)反对(0)
  
#24楼
2010-12-24 15:50 | hugangyong  
为什么不用com了
交互本来就是一个很麻烦的事情,一般情况是让善于写c++的人写一部分
善于c#的写一部分,如果他们的沟通,也就是在数据类型的认识上除了问题,工作怎么展开,比如cstring的类型对于C#的程序员很不理解,你让c#程序员在调用的时候怎么办,所以这样的工作还是交给com这样的平台来处理,我们还是尽量避免不必要的沟通,当然项目是根据具体情况变的。。。。。。。
一个人,他是牛人,他就喜欢一个项目搞多语言的链接库来组合,他自己很清楚怎么来调用,那当然没问题,也就是具体情况具体对待,但是目前的快餐语言没有那么多的时间来琢磨
我的QQ609210276
可以交流
支持(0)反对(0)
  
#25楼
2011-03-19 20:45 | niesen111  
第二种方法程序运行后怎么没输出呢
。。。。。

支持(0)反对(0)
  
#26楼
2011-12-05 18:04 | Zephyroal  
网上搜了一堆文章,头头是道,可没一个讲通的,多谢老兄,一个sample让小弟茅塞顿开~~
支持(0)反对(0)
  
#27楼
2012-12-03 16:12 | 江枫_2012  
楼主你好!我用测试程序可以正确调用硬件厂家提供的dll,但合并在程序中后,抛出“AccessViolationException 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”这个异常,麻烦帮我看看是哪里出问题了,引用厂家dll的代码如下:
[DllImport(@"termb.dll", EntryPoint = "CVR_InitComm",CharSet=CharSet.Ansi,SetLastError=false,CallingConvention=CallingConvention.StdCall)]
public static extern int CVR_InitComm(int Port);
程序中调用的代码如下:
int result = CVR_InitComm(2);
我邮箱地址:zhoujiangfeng_2008@163.com
谢谢!
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
dll库动态加载vs静态加载(小结)
DB2 静态 SQL 和动态 SQL 的比较与实践
CGI、FastCGI、CLI、Apache、ISAPI之PHP运行环境对比
鸟的世界◇动态◇静态[85P]1
error LNK2001:无法解析的外部符号___argc
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服