Как использовать неуправляемую DLL в приложении C ++ win32? - PullRequest
0 голосов
/ 26 декабря 2010

У меня есть сторонняя DLL, которую я пытаюсь использовать в Win32 C ++ приложении.Одна только DLL - это все, что у меня есть.Я полагаю, что эта библиотека написана на C, и я предполагаю, что не подвергается воздействию COM.Является ли LoadLibrary () функцией, обычно используемой для этой задачи в Windows?Если да, может ли кто-нибудь дать мне пример того, как он используется?

Я создал пустой win32 в VS, поэтому у меня не было никаких заголовков для окон и т. Д.

Спасибо!

UPDATE

Хочу добавить, что я пытаюсь использовать библиотеку SDL, которая, похоже, очень широко используется.Кажется странным, что поставщик не предоставит больше, чем DLL, если потребуется больше. Простой слой DirectMedia

Ответы [ 5 ]

2 голосов
/ 26 декабря 2010

Да, вы можете использовать LoadLibrary (на самом деле, если у вас есть только DLL, это единственный способ), но этого недостаточно.Чтобы использовать DLL, вы должны знать объявления открытых функций (возвращаемые типы, а также списки аргументов).В ответ вы не сможете использовать DLL.

0 голосов
/ 26 декабря 2010

Предполагая, что у вас есть доступ к заголовочному файлу или есть документация, которая идентифицирует функцию и их параметры - вот как это выглядит

Предположим, что функции выглядят следующим образом
int Func1 (inti1, int i2);
void Func2 (void);

Ниже приведен пример кода

#include windows.h  
#include stdio.h  
// use either dumpbin or http://www.dependencywalker.com/ to confirm the functions  
//Let us assume it has two functions with their prototypes known - Func1 & Func2  
int Func1 (int i1, int i2);  
void Func2(void);  
typedef int (*FUNC1_PTR) (int, int);  
typedef void (*FUNC2_PTR) (void);  
const char NONAME_DLL[] = "some.dll";  
int main(int argc, char *argv[]) {  
    FUNC1_PTR f1;  
    //FUNC2_PTR F2;  
    int i= 1, j = 2;  
    HMODULE hMod = LoadLibrary(NONAME_DLL);  
    if (!hMod) {  
        printf("LoadLibrary fails with error code %d \n", GetLastError());  
        return 1;  
    }  
    f1 = (FUNC1_PTR) GetProcAddress(hMod, "Func1");  
    if (f1) {  
        int ret = (*f1)(i, j);  
    }  
    FreeLibrary (hMod);  
    return 0;  
}  

Если у вас нет доступа к заголовочному файлу или вы не знаете сигнатуру функций - возможно, есть несколько способов продолжить
- Выполнитьпрограмма, использующая эту функцию и прерывающая работу с отладчиком, когда эта функция вызывается, и посмотреть, что она делает.
- Используйте интерактивный дизассемблер (например, IDA Pro), он может отображать такие элементы подписи, как количество передаваемых параметров.в функцию.
- Разборка функции для анализа ее пролога и эпилога.Это отнимает много времени и не является тривиальной задачей, в особенности из-за разных компиляторов, разных соглашений о вызовах, оптимизированных упаковщиков кода и т. Д.
- Я слышал, что люди говорили, что они использовали winedump - вы можете проверить это здесь http://www.winehq.org/docs/winedump - Я никогда не использовал это все же.Nirsoft.net DLL Export Viewer, возможно, является еще одним инструментом.
- Также это еще один инструмент - Visual dumpbin, использующий UnDecorateSymbolName, инструмент доступен по адресу http://code.entersources.com/f/Visual-Dumpbin-A-C--Visual-GUI-for-Dumpbin_2_1671_0.aspx. DLL должна быть собрана компилятором MS.Проверьте, что эта ссылка может дать вам больше подсказок, ...

0 голосов
/ 26 декабря 2010

Вам понадобится больше, чем просто DLL.По крайней мере, вам нужно знать функции, их параметры и семантику.Без этого вы не сможете практично использовать DLL.Лучше всего начать с обращения к поставщику DLL.

Но если вы застряли, вот несколько способов начать работу ...

Используйте dumpbin.exe, чтобы получить некоторую информациюпо поводу DLL.В качестве альтернативы вы можете использовать зависит от.exe для графического представления.Обе эти программы будут где-то в вашей папке Visual Studio.

dumpbin.exe / exports покажет вам экспортированные функции.Это функции, которые вы можете вызвать из своего приложения.Каждая функция имеет имя и порядковый номер, и вы можете использовать любой из них позже в GetProcAddress.

Если вы видите функции с именами DllCanUnloadNow, DllRegisterServer и т. Д., То это COM DLL.В этом случае вам понадобится соответствующая библиотека типов.Поставщик DLL, вероятно, отправит вам библиотеку типов, если вы спросите их.Некоторые библиотеки DLL хранят свои библиотеки типов как ресурсы - вы можете открыть библиотеку DLL непосредственно в Visual Studio и найти ресурс типа «TYPELIB».Если есть ресурс библиотеки типов, то вы можете экспортировать его и сохранить его как what.tlb, а затем открыть его в OleViewer или средстве просмотра типов Visual Studio - в любом случае, вы готовы начать играть.

Еслиэто не COM DLL, тогда вы можете использовать LoadLibrary, чтобы загрузить ее, а затем GetProcAddress, чтобы получить указатель на функцию.Однако, чтобы использовать функцию, вам придется привести возвращенный указатель FARPROC к указателю на функцию соответствующего типа - это не так просто, если вы новичок в такого рода вещах.

Если функцияимя в DLL искажено, что-то вроде? независимо от @@ YAHXZ, тогда это функция C ++, и вам придется использовать тот же компилятор, который использовался для сборки DLL.(Не обязательно, но по большому счету.) Но библиотеки DLL, написанные на C ++, часто экспортируют функции с привязкой к C, так что если вам повезет, вам не придется об этом беспокоиться.

dumpbin.exe / dependents покажет вамсписок других DLL, которые использует ваша DLL.Если вы видите mscoree.dll, то он использует .NET.В этом случае на вашем компьютере пользователя должна быть установлена ​​соответствующая среда .NET.

0 голосов
/ 26 декабря 2010

Вероятно, лучшее, что можно сделать здесь, - это определить класс, который будет выполнять вызов LoadLibrary, чтобы вы не могли забыть вызвать FreeLibrary позже.Например, см. https://bitbucket.org/BillyONeal/pevfind/src/ed3a0f5c37c4/pevFind/Win32RuntimeDynamicLinker.hpp

Обратите внимание, что вы действительно могли бы убрать здесь усиление - это только там, чтобы гарантировать, что сообщения об ошибках будут генерироваться во время компиляции, если кто-то попытается использовать WindowsApi::RuntimeDynamicLinker::GetFunction<t>, где tне является какой-либо формой указателя на функцию.

0 голосов
/ 26 декабря 2010

Вам необходимо вручную создать библиотеку импорта для своего приложения, чтобы связать и заголовочные файлы для включения. Надеюсь, это не C ++. Вот основные инструкции по началу работы: Как создать 32-битные библиотеки импорта без .OBJs или источника

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...