代码改变世界

C#调用非托管代码(C++方法)的2种方式

2013-05-14 15:53  无聊玩博客  阅读(629)  评论(0编辑  收藏  举报

第一种:静态调用  

使用using System.Runtime.InteropServices命名空间下的DllImport标签指定非托管的Dll及其细节

方法必须是静态的即必须加上static关键字,还有extern关键字

  [DllImport("kernel32.dll", EntryPoint = "GetSystemDefaultLCID")]
        static extern ushort GetSystemDefaultLCID();//OS 当前选择的默认语言(区域-管理)
        [DllImport("kernel32.dll", EntryPoint = "GetSystemDefaultLangID")]
        static extern ushort GetSystemDefaultLangID();//OS 当前选择的默认语言(区域-管理)

调用时与普通的静态方法一致;

第二种:动态加载

动态加载时需要使用的一些非托管代码

        //装载动态库
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);
        //获取要引入的函数
        [DllImport("kernel32.dll")]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
        //释放动态链接库
        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", SetLastError = true)]
        static extern bool FreeLibrary(IntPtr hModule);

 

首先定义相应的代理对应的非托管代码(dll)中的相关方法(我们需要的方法)

    public delegate int dicCreateHDICT(int dwWordLangID, string lpcszIdxFileName, string lpcszDatFileName);
    public delegate bool dicFreeHDICT(int hdict);

再动态加载非托管代码

  public class DLLHandler
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);
        //获取要引入的函数
        [DllImport("kernel32.dll")]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
        //释放动态链接库
        [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", SetLastError = true)]
        static extern bool FreeLibrary(IntPtr hModule);
        //DrDicEnt.dll
        public static dicCreateHDICT dictCreateDICT = null;
        public static dicFreeHDICT dictFreeDict = null;
        public static void Init()
       {
         IntPtr hLib=LoadLibrary(@"D:\Dll\DrDicEnt.dll");
         IntPtr api = GetProcAddress(hLib,"dicCreateHDICT");
     dictCreateDICT = (dicCreateHDICT)Marshal.GetDelegateForFunctionPointer(api,typeof(dicCreateHDICT));
 IntPtr api2 = GetProcAddress(hLib,"dicFreeHDICT");
     dicFreeHDICT= (dicFreeHDICT)Marshal.GetDelegateForFunctionPointer(api2,typeof(dicFreeHDICT));

}

调用时先DLLHandler.Init();
再使用DLLHandler.dicCreateHDICT()等方法