C#はC++のDLL関数のもう一つの(delegate)zを呼び出します
8627 ワード
DLImportを使用して関数をインポートすること.C#がC++を呼び出す関数は実はこの方法だけではなく、delegateで関数の依頼を明示して呼び出す方法もあり、この方法はやや面倒であるが、コールバックを行いポインタを適用することができる.
C#では、まずDLLの関数アドレスを委任に変換するクラスを定義します.
次にdelegateで関数を宣言します.
それから、自分でprivateの関数を書いてDLLの中の関数をカプセル化して、hModule()関数の作用はDLLのアドレスを取得して、複数の出力関数の中で使います
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;
}
}