まず、dllimport 属性と getProcAddress 関数を直接比較しても意味がないことはわかっています。むしろ、dllimport 属性または getProcAddress 関数を使用して関数をインポートすることにより、基本的に同じこと (dll で関数を呼び出す) を実現する 2 つのコードを比較することに興味があります。具体的には、私が作成した dll の関数を使用する C# アプリケーションを作成しています。最初に、次のコードで dll 関数にアクセスしました。
class DllAccess
{
[DllImport("kernel32.dll", SetLastError = true)]
private extern IntPtr LoadLibrary(String DllName);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate Bool BarType(Byte arg); // return value indicates whether function call went well or not.
Bool Bar(Byte arg)
{
Bool ok = false;
IntPtr pDll= LoadLibrary("foo.dll");
if (pDll != IntPtr.Zero)
{
IntPtr pfunc = GetProcAddress(pDll, "bar");
if (pFunc != IntPtr.Zero)
{
BarType bar = (BarType)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(BarType));
ok = bar(arg);
}
FreeLibrary(pDll);
}
return ok;
}
}
ただし、dll 呼び出し中に設定されていた場合は、後で lastError 値を取得する必要があったため、コードを次のように変更しました。
class DllAccess
{
[DllImport("foo.dll", EntryPoint = "bar", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private extern Bool DllBar(Byte arg); // return value indicates whether function call went well or not.
Bool Bar(Byte arg)
{
return DllBar(arg);
}
}
もちろん、これははるかに整頓されており、前述のように、lastError コードを設定します。明らかに、私の最初のコードでは、実行時に dll と関数呼び出しを変更できる可能性がありますが、現時点ではこれは必要ありません。したがって、私の質問は次のとおりです。別のdllまたは別の関数を使用しないことが確実である場合、最初の定式化を使用する理由はありますか?