C#与C++的互操作

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

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

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

 2. 在DllDemo.cpp文件中添加这些代码。 Code extern "C" __declspec(dllexport) int Add(int a,int b) { return a+b; }    

3. 编译工程。   

  4. 建立新的C#工程,选择Console应用程序,建立测试程序InteropDemo

5. 在Program.cs中添加引用:using System.Runtime.InteropServices;    

6. 在pulic class Program添加如下代码:    Code using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace InteropDemo { class Program { [DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] public static extern int Add(int a, int b); //DllImport请参照MSDN static void Main(string[] args) { Console.WriteLine(Add(1, 2)); Console.Read(); } } }   

 好了,现在您可以测试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 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace InteropDemo { public static class NativeMethod { [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")] public static extern int LoadLibrary( [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")] public static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")] public static extern bool FreeLibrary(int hModule); } }    

 2. 使用NativeMethod类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。原因很简单,C#中已经不能使用指针了,如下          int hModule = NativeMethod.LoadLibrary(@"c:"CppDemo.dll");             IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add"); 详细请参见代码 Code using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace InteropDemo { class Program { //[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] //public static extern int Add(int a, int b); //DllImport请参照MSDN static void Main(string[] args) { //1. 动态加载C++ Dll             int hModule = NativeMethod.LoadLibrary(@"c:\CppDemo.dll"); if (hModule == 0) return; //2. 读取函数指针             IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add"); //3. 将函数指针封装成委托             Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add)); //4. 测试             Console.WriteLine(addFunction(1, 2)); Console.Read(); } ///  /// 函数指针 ///  ///  ///  ///          delegate int Add(int a, int b); } }

通过如上两个例子,我们可以在C#中动态或者静态的调用C++写的代码了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值