• C#调用C++的DLL函数另一则(delegate) z


    使用DLLImport进行导入函数的事. C#调用C++的函数其实不止这一种方法, 还有一种方法是用delegate申明函数委托进行调用,这种方法略显麻烦,但是可以进行回调并应用指针.

    在C#中,首先先要定义一个类,用来把DLL中函数地址转换成委托:

        public class DLLWrapper
        {
        ///<summary>
        /// API LoadLibrary
        ///</summary>
        [DllImport("Kernel32")]
        public static extern int LoadLibrary(String funcname);
         
        ///<summary>
        /// API GetProcAddress
        ///</summary>
        [DllImport("Kernel32")]
        public static extern int GetProcAddress(int handle, String funcname);
         
        ///<summary>
        /// API FreeLibrary
        ///</summary>
        [DllImport("Kernel32")]
        public static extern int FreeLibrary(int handle);
         
        ///<summary>
        ///通过非托管函数名转换为对应的委托, by jingzhongrong
        ///</summary>
        ///<param name="dllModule">Get DLL handle by LoadLibrary</param>
        ///<param name="functionName">Unmanaged function name</param>
        ///<param name="t">ManageR type对应的委托类型</param>
        ///<returns>委托实例,可强制转换为适当的委托类型</returns>
        public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
        {
        int address = GetProcAddress(dllModule, functionName);
        if (address == 0)
        return null;
        else
        return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
        }
         
        ///<summary>
        ///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong
        ///</summary>
        public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
        {
        if (address == IntPtr.Zero)
        return null;
        else
        return Marshal.GetDelegateForFunctionPointer(address, t);
        }
         
        ///<summary>
        ///将表示函数地址的int转换成对应的委托,by jingzhongrong
        ///</summary>
        public static Delegate GetDelegateFromIntPtr(int address, Type t)
        {
        if (address == 0)
        return null;
        else
        return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
        }
        }

    然后, 用delegate声明函数:

        delegate void _amDBRSetThermoModel(int mid, ref int errid);

    再然后, 自己写个private的函数封装DLL中的函数, hModule()函数的作用是取得DLL的地址,用在多个输出函数中

        private int hModule()
        {
        int _hModule = DLLWrapper.LoadLibrary(DLLPATH);
        if (_hModule == 0)
        {
        return 0;
        }
        return _hModule;
        }
         
        private void amDBRInitialize()
        {
        try
        {
        _amDBRInitialize amf = (_amDBRInitialize)DLLWrapper.GetFunctionAddress(hModule(), "amDBRInitialize", typeof(_amDBRInitialize));
        amf();
        }
        catch (Exception e)
        {
        throw e;
        }
        }
  • 相关阅读:
    线程总结(1)
    (转)远程线程DEMO
    VCL 中TList源码分析
    MVC Controller向View传值(ViewData与ViewBag)
    ASP.NET MVC 下拉框的传值的两种方式(第二种方式未完成)
    将数据在[Excel]和[任何数据源]之间导入导出_可临时保存查询结果
    服务器控件之二
    关闭窗口动画,加速窗口
    让XP控制台字符编码在UTF8与GBK之间切换
    WCF应用的编码实现
  • 原文地址:https://www.cnblogs.com/zeroone/p/3681379.html
Copyright © 2020-2023  润新知