Нужен ли файл .LIB для вызова DLL в C ++, но не для C # P / Invoke? - PullRequest
2 голосов
/ 24 апреля 2011

Я искал ответы о том, как ссылаться на неуправляемые библиотеки DLL из C ++,

Есть ли лучший способ загрузить DLL в C ++?

Ссылки на DLL в Visual C ++

и кажется, что DLL не может быть загружена в C ++ без вызывающей стороны, также имеющей файл .LIB . Правда ли, что файл .lib абсолютно необходим, если я хочу динамически загружать DLL во время выполнения следующим образом?

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

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

Если я вызываю LoadLibrary с использованием кода выше, я получаю результат NULL. Код ошибки из GetLastError (): 193: ERROR_BAD_EXE_FORMAT . Почему?

EDIT / UPDATE: Я понял, что не так - у меня была целевая платформа программы (которая вызывает DLL) как x64, и как только я изменил ее на Win32, LoadLibrary теперь возвращает ненулевой результат.

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;
}

Вот как это скомпилировано:

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

Если я использую известную DLL-библиотеку, например unrar3.DLL, я все равно получаю код ошибки 193. Почему я получаю этот код ошибки?

С другой стороны, если я использую P / Invoke в управляемом C #, все, что мне нужно, это полный путь к .DLL, файл LL не нужен, и вызов функции для 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);

Ответы [ 3 ]

5 голосов
/ 24 апреля 2011

LIB-файлы необходимы только в том случае, если вы хотите связать статически (что вызывает сильную зависимость между вашим двоичным файлом и библиотекой DLL: ваш двоичный файл не будет загружаться, если библиотека DLL отсутствует). LoadLibrary() (или LoadLibraryEx()) обходит все это: но, с другой стороны, вы должны установить указатели функций на все точки входа, используя GetProcAddress () (или GetProcAddressEx()) с порядковым номером экспортируемой функции или ее имя, которое может быть хлопот. Последнее то, что C # делает с DllImport, с более дружественным синтаксисом.

2 голосов
/ 24 апреля 2011

.lib используется только для __declspec(dllexport) или для импорта / экспорта специфичной для C ++ библиотеки Microsoft.P / Invoke аналогичен файлам .DEF и использует GetProcAddress, который представляет собой импорт / экспорт DLL в стиле C.Два не являются взаимозаменяемыми.

2 голосов
/ 24 апреля 2011

Нет, вы можете вызвать LoadLibrary, а затем GetProcAddress для любой DLL во время выполнения - вам понадобится .LIB, только если вы хотите статически связываться с DLL (то есть сразу после компиляции).

...