首先,我知道直接比较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