是否.LIB文件需要在C++中调用DLL而不是C#P/Invoke?

T. *_*ter 2 c++ dll dllimport loadlibrary visual-c++

我一直在寻找如何从C++引用非托管DLL的答案,

有没有更好的方法在C++中加载DLL?

Visual C++中的DLL引用

并且看起来如果没有调用者也有.LIB文件,则无法在C++中加载DLL .如果我想在运行时动态加载DLL,如果真的需要.lib文件,如下所示?

   #include <Windows.h>
    HMODULE h;  
    LPCWSTR l;  
    DWORD error;
    wchar_t *myDLL = L"E:\\...\\myWin32DLL.dll";

    l = (LPCWSTR)myDLL;
    h = LoadLibrary(l);     
    error = GetLastError();  
Run Code Online (Sandbox Code Playgroud)

如果我使用上面的代码调用LoadLibrary,我得到的结果为NULL.GetLastError()的错误代码是193:ERROR_BAD_EXE_FORMAT.为什么?

编辑/更新: 我想出了什么是错的 - 我有程序的目标平台(调用DLL)为x64,一旦我将其更改为Win32,LoadLibrary现在返回非NULL结果.

DLL由一个源文件expFns.cpp组成:

#include <Windows.h>

#define Pi 3.14159

extern _declspec(dllexport)  
double circumference(double radius)
{
    return 2.0 * radius * Pi;
}
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

以下是它的编译方式:

cl expFns.cpp /link /DLL /out:mywin32dll.dll
Run Code Online (Sandbox Code Playgroud)

如果我使用一些众所周知的DLL,如unrar3.DLL,我仍然会收到错误代码193.为什么我收到此错误代码?

另一方面,如果我在托管C#中使用P/Invoke,我只需要.DLL的完整路径,不需要.LIB文件,并且DLL的函数调用将起作用.为什么C++中必须有.LIB文件,但C#不需要.LIB文件?

[DllImport(@"E:\...\myDLL.dll"
            , CallingConvention = CallingConvention.Cdecl
            , EntryPoint = "get_value")]
internal static extern double get_value(double l, double w, double h);
Run Code Online (Sandbox Code Playgroud)

Pon*_*gge 5

只有在想要静态链接时才需要LIB文件(强制二进制文件和DLL之间存在强依赖关系:如果DLL不存在,则不会加载二进制文件).LoadLibrary()(或 LoadLibraryEx())绕过所有这些:但另一方面,您必须使用GetProcAddress()(或GetProcAddressEx())设置所有入口点的函数指针,其中包含导出函数的序号或其名称,这可能很麻烦.后者是C#所做的DllImport,具有相当友好的语法.

  • DLL没有静态链接.它们是动态链接的.那是DLL中的'D'.当您说"静态链接"时,您的意思是隐式动态链接.显式动态链接是`GetProcAddress()`. (2认同)