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;
    }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM