首先,我知道直接比較dllimport屬性和getProcAddress函數是沒有意義的。相反,我有興趣比較兩段代碼,它們實現了基本相同的功能 - 通過導入具有dllimport屬性的函數或getProcAddress函數來調用dll中的函數。具體來說,我正在編寫一個C#應用程序,它在我編寫的dll中使用了一些函數。起初,我訪問我的DLL函數與下面的代碼:dllimport和getProcAddress之間的區別
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;
}
}
不過,後來我需要得到在lastError價值,如果它的DLL調用過程中設置,所以我改變了我的代碼到這個:
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或其他函數?
謝謝你的回答。在我的代碼中,我實際上在構造函數中加載了庫,在析構函數中釋放了庫,並將所有內容作爲單例使用,因爲我不知道是否會導致不止一次加載庫。爲了保證正確性,我編輯了我的帖子,同時釋放圖書館。 – Boris 2010-07-13 23:52:28
@Boris:'LoadLibrary'和'FreeLibrary'做引用計數,所以多次調用都可以正常工作。 – 2010-07-13 23:58:50
你是什麼意思的「泄漏地址」?該DLL只加載一次,內存中只存在該函數的一個副本,並且該代理被垃圾收集。 – 2010-07-14 00:00:31