C#加载动态链接库的类

今天用C#完美调用成功了金橙子的二次开发库。(虽然加载成功,但是不知道为什么在初始化函数一直返回的是21的错误,对照说明error21为错误的硬件参数,还需好好研究。)

DldClass是调用动态链接库的类

using System;
using System.Runtime.InteropServices; // 用 DllImport 需用此 命名空间  

namespace DemoJcz
{
    public class DldClass
    {
        /// <summary>  
        /// 原型是 :HMODULE LoadLibrary(LPCTSTR lpFileName);  
        /// </summary>  
        /// <param name="lpFileName">DLL 文件名 </param>  
        /// <returns> 函数库模块的句柄 </returns>  
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern IntPtr LoadLibrary(string lpFileName);

        /// <summary>  
        /// 原型是 : FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName);  
        /// </summary>  
        /// <param name="hModule"> 包含需调用函数的函数库模块的句柄 </param>  
        /// <param name="lpProcName"> 调用函数的名称 </param>  
        /// <returns> 函数指针 </returns>  
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

        /// <summary>  
        /// 原型是 : BOOL FreeLibrary(HMODULE hModule);  
        /// </summary>  
        /// <param name="hModule"> 需释放的函数库模块的句柄 </param>  
        /// /// <returns> 是否已释放指定的 Dll</returns>  
        [DllImport("kernel32", EntryPoint = "FreeLibrary", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        static extern bool FreeLibrary(IntPtr hModule);

        /// <summary>  
        /// Loadlibrary 返回的函数库模块的句柄  
        /// </summary>  
        private IntPtr hModule = IntPtr.Zero;

        /// <summary>  
        /// GetProcAddress 返回的函数指针  
        /// </summary>  
        private IntPtr farProc = IntPtr.Zero;

        /// <summary>  
        /// 装载 Dll 
        /// </summary> 
        /// <param name="lpFileName">DLL 文件名 </param> 
        public void LoadDll(string lpFileName)
        {
            hModule = LoadLibrary(lpFileName);
            if (hModule == IntPtr.Zero)
                throw (new Exception(" 没有找到 :" + lpFileName + "."));
        }

        public void LoadDll(IntPtr HMODULE)
        {
            if (HMODULE == IntPtr.Zero)
                throw (new Exception(" 所传入的函数库模块的句柄 HMODULE 为空 ."));
            hModule = HMODULE;
        }

        /// <summary>  
        /// 获得函数指针  
        /// </summary>  
        /// <param name="lpProcName"> 调用函数的名称 </param>  
        public void LoadFun(string lpProcName)
        { // 若函数库模块的句柄为空,则抛出异常  
            if (hModule == IntPtr.Zero)
                throw (new Exception(" 函数库模块的句柄为空 , 请确保已进行 LoadDll 操作 !"));

            // 取得函数指针  
            farProc = GetProcAddress(hModule, lpProcName);

            // 若函数指针,则抛出异常  
            if (farProc == IntPtr.Zero)
                throw (new Exception(" 没有找到 :" + lpProcName + " 这个函数的入口点 "));

        }

        /// <summary>  
        /// 获得函数指针  
        /// </summary>  
        /// <param name="lpFileName"> 包含需调用函数的 DLL 文件名 </param>  
        /// <param name="lpProcName"> 调用函数的名称 </param>  
        public void LoadFun(string lpFileName, string lpProcName)
        { // 取得函数库模块的句柄  
            hModule = LoadLibrary(lpFileName);

            // 若函数库模块的句柄为空,则抛出异常  
            if (hModule == IntPtr.Zero)
                throw (new Exception(" 没有找到 :" + lpFileName + "."));

            // 取得函数指针  
            farProc = GetProcAddress(hModule, lpProcName);
            // 若函数指针,则抛出异常  
            if (farProc == IntPtr.Zero)
                throw (new Exception(" 没有找到 :" + lpProcName + " 这个函数的入口点 "));
        }

        /// <summary>  
        /// 卸载 Dll  
        /// </summary>  
        public void UnLoadDll()
        {
            FreeLibrary(hModule);
            hModule = IntPtr.Zero;
            farProc = IntPtr.Zero;
        }
        
        public DldClass(String DLLPath)
        {
            LoadDll(DLLPath);
        }
        ~DldClass()
        {
            FreeLibrary(hModule);
        }

        //将要执行的函数转换为委托
        public Delegate Invoke(String APIName, Type t)
        {
            IntPtr api = GetProcAddress(hModule, APIName);
            return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
        }
    }
}

初始化LMC程序

public delegate int LMC1_INITIAL([MarshalAs(UnmanagedType.LPWStr)] string strEzCadPath,//ezcad的工作目录
                                            int bTestMode,//是否是测试模式
                                            IntPtr hOwenWnd);//父窗口
public delegate int LMC1_LOADEZDFILE([MarshalAs(UnmanagedType.LPWStr)] string strFileName);//zed文件地址

private DldClass dld = new DldClass("MarkEzd.dll");

private void Form1_Load(object sender, EventArgs e)
{
    try
    {
        //DldClass dld = new DldClass("MarkEzd.dll");
        if (dld == null)
        {
            return;
        }
                
        dld.LoadFun("lmc1_Initial");              
        dld.LoadFun("lmc1_LoadEzdFile");

        LMC1_INITIAL lmc1_Initial = (LMC1_INITIAL)dld.Invoke("lmc1_Initial", typeof(LMC1_INITIAL));
        string dir = Application.StartupPath;
        int _bTestMode = 0;//是否为测试模式
        IntPtr _hOwenWnd = this.Handle;//用户输入焦点的窗口,用于检测用户暂停消息
        int nErr = lmc1_Initial(dir, _bTestMode, _hOwenWnd);
        if (nErr != 0) //这里就是调用我的DLL里定义的Compile函数
        {
            MessageBox.Show("Initial=" + nErr.ToString());
            //Application.Exit();
        }

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        Application.Exit();
    }
}

错误21的问题已经解决,只需联系金橙子厂家在线更新加密狗驱动即可消除(emm……因为厂家对二次开发做了加密处理,好麻烦啊)

win7及以上版本的驱动可在金橙子官网里下载对应的驱动。(我居然还傻傻的装了个xp去玩0.0心疼……)

软件调试的话,可在初始化时 int _bTestMode = 1;


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
动态链接库(Dynamic Link Library,DLL)和静态库(Static Library)都是常见的库文件形式,用于在编程中重用代码。 静态库是一组已经编译好的对象文件的集合,它们被静态地链接到可执行文件中。在编译时,静态库的代码会被复制到可执行文件中,因此可执行文件本身包含了所有需要的代码。静态库的优点是方便部署,因为可执行文件独立于外部依赖,不需要额外的库文件。但是,静态库的缺点是每个可执行文件都会包含一份代码副本,因此可能会造成代码冗余和文件体积较大。 动态链接库是一组已经编译好的对象文件的集合,它们在运行时被动态地加载到内存中。在编译时,可执行文件只包含对动态链接库的引用,而不是实际的代码。在程序运行时,操作系统会根据引用去查找并加载相应的动态链接库动态链接库的优点是节省内存空间,因为多个可执行文件可以共享同一个动态链接库的实例。此外,如果动态链接库发生更新或修复,只需要替换库文件本身而无需重新编译可执行文件。然而,动态链接库的缺点是部署时需要额外的库文件,而且对于不同的操作系统和体系结构可能需要不同的库文件。 在C#中,动态链接库通常采用.dll后缀,而静态库通常采用.lib后缀。可以使用.NET平台的工具(如C#编译器或Visual Studio)来编译和生成库文件。对于动态链接库,可以使用DllImport属性或者使用.NET平台提供的InteropServices命名空间中的相关来引用和调用其中的函数。对于静态库,可以将其链接到可执行文件中,或者使用.NET平台提供的工具(如ILMerge)将其合并到可执行文件中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值