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.
精彩评论