开发者

Is .LIB file needed to call DLL in C++ but not for C# P/Invoke?

I have been looking for answers on how to reference unmanaged DLLs from C++,

Is there a better way to load a dll in C++?

DLL References in Visual C++

and it appears that a DLL cannot be loaded in C++ without the caller also having the 开发者_如何学编程.LIB file. Is this true that the .lib file is absolutely required if I want to dynamically load a DLL at run-time as follows?

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

    l = (LPCWSTR)myDLL;
    h = LoadLibrary(l);     
    error = GetLastError();  

If I call LoadLibrary using the code above, I get the result NULL. The error code from GetLastError() is 193: ERROR_BAD_EXE_FORMAT. Why?

EDIT/UPDATE: I figured out what's wrong -- I had the target platform of the program (that calls the DLL) as x64, and once I changed it to Win32, LoadLibrary now returns a non-NULL result.

The DLL is made up of one source file, 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;
}

Here is how it is compiled:

cl expFns.cpp /link /DLL /out:mywin32dll.dll

If I use some well-known DLL such as unrar3.DLL, I still get error code 193. Why am I getting this error code?

On the other hand, if I use P/Invoke in managed C#, all I need is the full path to the .DLL, no .LIB file needed, and the function call to the DLL will work. Why is it necessary in C++ to have the .LIB file, but C# does not need the .LIB file?

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


LIB files are only needed if you want to link statically (forcing a strong dependency between your binary and the DLL: your binary won't load if the DLL isn't present). LoadLibrary() (or LoadLibraryEx()) bypasses all that: but on the other hand, you have to setup function pointers to all entry points using GetProcAddress() (or GetProcAddressEx()) with either the ordinal number of the exported function or its name, which can be a hassle. The latter is what C# does with DllImport, with a rather more friendly syntax.


Nope, you can call LoadLibrary and then GetProcAddress on any DLL at runtime - you only need the .LIB if you want to link against the DLL statically (i.e. just after compilation).


The .lib is used for __declspec(dllexport) only, or Microsoft's C++ specific DLL import/export. P/Invoke is the same as .DEF files and uses GetProcAddress, which is C-style DLL import/export. The two are not interchangable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜