С++ DLL не будет связываться?

Хорошо, вот в чем дело. Пытаясь углубить свои знания API-интерфейсов C++, я попытался узнать больше о типах файлов библиотек. Я довольно хорошо разобрался со статическими библиотеками. Вы просто подключаете библиотеку к проекту, и ее содержимое помещается в двоичные файлы при компиляции и компоновке. Но я столкнулся с проблемой, когда начал пытаться использовать динамические библиотеки. Мне удалось успешно скомпилировать файл DLL с помощью функции __declspec и создать внешние блоки (чтобы его можно было успешно экспортировать в C++). Но проблема возникает, когда я пытаюсь связать файл. На основе нескольких руководств, которые я видел в Интернете, я создаю заголовок с предварительными определениями и включаю его в исполняемый проект. Затем я обязательно добавляю каталог поиска в настройки сборки проекта вместе с путем к импортируемой библиотеке. Затем, когда я иду собирать проект, он выдает ошибку компоновщика (я могу сказать, потому что объектный файл скомпилирован) «не удается найти -l [путь к файлу]». Будут ли сделаны дополнительные настройки? Я предполагаю, что это как-то связано с моим компилятором (MinGW), потому что Code::Blocks (в настоящее время я использую плагин Eclipse CDT) вызвал аналогичную ошибку ссылки.

Если вам нужно увидеть код, я предоставлю его ниже.

// EXE: main.cpp
#include <iostream>
#include "DLLTutorial.h"

int main()
{
    Function();
    std::cout << "1 + 3:\t" << Add(1, 3);
}


// DLL: DLLTutorial.cpp
#define DLL_EXPORT
#include <iostream>
#include "DLLTutorial.h"

extern "C"
{
    DLLCOMP int Add(int a, int b)
    {
        return a + b;
    };

    DLLCOMP void Function(void)
    {
        std::cout << "DLL Called!\n";
    };
};


// DLL: DLLTutorial.h
#ifndef DLLTUTORIAL_H_
#define DLLTUTORIAL_H_

#include <iostream>

#ifdef DLL_EXPORT
    #define DLLCOMP __declspec(dllexport)
#else
    #define DLLCOMP __declspec(dllimport)
#endif

extern "C"
{
    DLLCOMP int Add(int a, int b);
    DLLCOMP void Function(void);
};


#endif /* DLLTUTORIAL_H_ */

Это просто очень простой пример кода, который я использовал с веб-сайта. Я не могу правильно связать исполняемый файл, поэтому я был бы признателен за любой совет, который можно было бы мне дать.

Кроме того, у меня есть связанный с этим вопрос. Прочитав несколько руководств в Интернете, некоторые упомянули, что функция __declspec специфична для Windows/Microsoft. Это правда? В таком случае, что было бы хорошим эквивалентом для использования в других операционных системах?


person B3tturTh3nU    schedule 06.12.2010    source источник


Ответы (2)


Когда вы создаете dll, вы также создаете корпоративный файл .lib, «implib». Вы должны статически связать этот файл в вашем exe.

РЕДАКТИРОВАТЬ: __cdeclspec(...) действительно Microsoft. Насчет других платформ не знаю.

person engf-010    schedule 06.12.2010
comment
Я предполагаю, что компоновщик не создает для вас статическую библиотеку (по крайней мере, без соответствующих настроек)? Потому что я не могу найти соответствующий файл lib в каталоге сборки для моего проекта. - person B3tturTh3nU; 06.12.2010
comment
Затем посмотрите рядом с файлом dll (вы случайно не использовали свое имя пользователя в качестве пароля?) - person ruslik; 06.12.2010
comment
Могут быть настройки компоновщика, которые препятствуют этому. Я не использую MinGw. Там также может быть def-файл, который можно использовать. - person engf-010; 06.12.2010
comment
@ Эдвин: Верно. Я использую mingw, и по умолчанию он не создает никаких файлов .lib. - person ruslik; 06.12.2010
comment
Поскольку вы также используете MinGW, знаете ли вы, что мне нужно изменить, чтобы он генерировал статическую библиотеку вместе с динамической? - person B3tturTh3nU; 06.12.2010
comment
@ruslik: Расскажите, какие настройки настроить. - person engf-010; 06.12.2010
comment
Этот сопровождающий файл называется 'implib' для библиотеки импорта. - person bmargulies; 06.12.2010

Вам нужно указать компилятору, где искать ваши библиотеки и включения. Как в GCC, так и в MinGW это достигается использованием -I для включений и -L для библиотек. Я не думаю, что вам необходимо генерировать .lib (или .a, как это обычно бывает в *nix и GCC), GCC сможет найти вашу функцию в dll.

Например, создайте и свяжите общую библиотеку:

g++ -shared -olibmy_dll.dll my_dll.cpp

Затем, предполагая, что все файлы находятся в одном и том же каталоге, создайте и свяжите исполняемый файл и сообщите GCC, чтобы он использовал вашу библиотеку:

g++ -oapp.exe app.cpp -lmy_dll -L.

Обратите внимание на разницу между -l и -L: один сообщает GCC, какие библиотеки использовать, а другой говорит, где их искать. В Eclipse CDT эти настройки находятся в: Свойства проекта -> Сборка C/C++ -> Настройки -> Компоновщик MinGW C++ -> Библиотеки.

Кроме того, __declspec распознается MinGW, но я все равно думаю, что это специфично для Microsoft.

person javs    schedule 06.12.2010