C#はC++のDLL関数のもう一つの(delegate)zを呼び出します

8627 ワード

DLImportを使用して関数をインポートすること.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;

    }

    }