代码之家  ›  专栏  ›  技术社区  ›  Boris

dllimport和getProcAddress之间的差异

  •  5
  • Boris  · 技术社区  · 14 年前

    首先,我知道直接比较dllimport属性和getProcAddress函数是没有意义的。相反,我感兴趣的是比较两段代码,它们实现了基本相同的功能—在dll中调用函数—通过使用dllimport属性或getProcAddress函数导入函数。具体来说,我正在编写一个C应用程序,它在我编写的dll中使用一些函数。首先,我使用以下代码访问了我的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;
        }
    }
    

    但是,如果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);
        }
    }
    

    这当然要整洁得多,正如前面提到的,它设置了最后一个错误代码。显然,我的第一段代码提供了在运行时更改dll和函数调用的可能性,但目前这不是必需的。所以我的问题是:如果我确信我不会使用另一个dll或另一个函数,那么使用第一个公式有什么理由吗?

    2 回复  |  直到 14 年前
        1
  •  5
  •   Reed Copsey    14 年前

    使用GetProcAddress的唯一真正优点是,您可以手动卸载DLL并调用函数,并且可以在运行时轻松更改命名。

    然而,第二种选择为您提供了大量的好处。除了“整洁”之外,它还为您处理许多数据类型的封送—这对于某些API来说非常重要。

    这就是说,如果您使用列出为第一个的方法,那么也应该确保卸载所有内容。现在,每次调用Bar()时基本上都在泄漏地址。。。有关详细信息,请参阅 FreeLibrary .

        2
  •  4
  •   Ben Voigt Caesar    14 年前

    可能是 GetProcAddress 它允许您控制DLL的搜索路径。例如,可以自动加载32位或64位版本的本机DLL。与 DllImportAttribute ,这是不可能的。