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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值