C#调用C++动态链接库DLL的方法大全

举报
资源描述
在最近的项目中,牵涉到项目源代码保密问题,由于代码是 C#写的,容易被反编译,因此决定抽取核心算法部分使用 C+编写,C+到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译。这样一来,就涉及 C#调用 C+编写的动态链接库,于是调查了一些资料,顺便与大家分享一下:一一一一.C#中静态调用中静态调用中静态调用中静态调用 C+的的的的动态链接动态链接动态链接动态链接库库库库 1.建立 VC 工程 CppDemo,建立的时候选择 Win32 Console(dll),选择 Dll。2.在 DllDemo.cpp 文件中添加这些代码。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 添加如下代码: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用法本文最末尾有详细介绍 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、GetProcAddress、FreeLibrary 这几个函数动态调用 Dll(它们包含在kernel32.dll 中),那么问题就迎刃而解了,下面我们一步一步的实验。1.将 kernel32 中的几个方法封装成本地调用类 NativeMethod 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);详细请参见代码 using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace InteropDemo class Program 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+写的代码了。附上附上附上附上 DllImportDllImportDllImportDllImport 的具体用法的具体用法的具体用法的具体用法 DllImport 所在的名字空间 using System.Runtime.InteropServices;MSDN 中对 DllImportAttribute 的解释是这样的:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 DLL 的名称。DllImport 属性定义如下:namespace System.Runtime.InteropServices AttributeUsage(AttributeTargets.Method)public class DllImportAttribute:System.Attribute public DllImportAttribute(string dllName)public CallingConvention CallingConvention;public CharSet CharSet;public string EntryPoint;public bool ExactSpelling;public bool PreserveSig;public bool SetLastError;public string Value get 说明:1、DllImport 只能放置在方法声明上。2、DllImport 具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。3、DllImport 具有五个命名参数:a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。f、SetLastError 参数指示方法是否保留 Win32上一错误。如果未指定 SetLastError,则使用默认值 false。4、它是一次性属性类。5、此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。联系方式 快乐的军队 最后编辑于 2010-7-14
展开阅读全文
温馨提示:
金锄头文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
相关资源
正为您匹配相似的精品文档
相关搜索

当前位置:首页 > 办公文档 > PPT模板库 > 总结/计划/报告


电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号