2016-09-28 4 views
0

Я где-то слышал, что все окна .dlls сусла содержит определения для каждого символа он ссылается, поэтому .DLL файл, как это никогда не будет компилировать, так как он не реализует bar().компилировать .dll с некоторыми неопределенными ссылками с MinGW

void bar(); 

__declspec(dllexport) 
void foo() { 
    bar(); 
} 

Я думаю, аналогия, что .dlls, по существу, исполняемый с другой точкой входа, так что они должны все Реферировано определены, как исполняемый файл.

Но в среде Unix я могу скомпилировать это .so-файл без проблем. Затем я могу использовать dlopen(path, RTLD_NOW | RTLD_GLOBAL); из приложения-хозяина для загрузки библиотеки и объединения символов хоста с библиотекой. Если хост определяет bar(), библиотека просто вызовет эту функцию.

Я не могу просто переопределить все в файл .DLL, потому что в моем приложении библиотека использует тысячи символов от хоста. Используя MinGW или, возможно, Visual C++, действительно ли нет способа использовать символ из хоста, оставив его неопределенным в .DLL и слиянием его при загрузке? Я также не хочу устанавливать тысячи функций обратного вызова в .DLL, потому что это затрудняет использование C++-методов.

+2

Вы слышали неправильно. Windows DLL может использовать символ из исполняемого файла, который загружает его, хотя это немного необычно. Вы просто экспортируете функцию из исполняемого файла (например, используя '__declspec (dllexport)') и импортируете его в DLL (например, используя '__declspec (dllimport)'). –

+0

... хотя теперь, когда я думаю об этом, я не знаю, поддерживает ли MinGW это. Я не понимаю, почему это не *, но я не знаю. –

+0

Я готов использовать Visual C++, если это необходимо, но я просто счастлив, что это возможно. Я перечитываю, как работает 'dllimport', потому что я, должно быть, неправильно понял что-то в прошлый раз. – Vortico

ответ

2

Я понял, как это сделать с MinGW.

Обычно, при компоновке DLL файлов (например, plugin.dll), экспортировать список символов libplugin.a, но в этом случае, я на самом деле хочу, чтобы экспортировать символы из принимающей исполняемого host.exe в libhost.a.

x86_64-w64-mingw32-g++ -o host.exe host.cpp -Wl,--out-implib,libhost.a

Это создает список символов, которые можно связать с при создании вашего плагина.

x86_64-w64-mingw32-g++ -shared -o plugin.dll plugin.cpp -L. -lhost

Это создает DLL, используя libhost.a файл (в текущем каталоге "").

Теперь, это немного раздражает, чтобы заполнить ваш код хоста __declspec(dllexport), чтобы вы могли добавить флаг компоновщика --export-all-symbols. И по какой-то причине, похоже, для этого не требуется атрибутов _declspec(dllimport), но я не знаю почему. Таким образом, вы можете скомпилировать хост с

x86_64-w64-mingw32-g++ -o host.exe host.cpp -Wl,--export-all-symbols,--out-implib,libhost.a

+0

См. Http://stackoverflow.com/a/4490536/886887, '__declspec (dllimport)' не требуется, но позволяет компоновщику оптимизировать вызовы. (Хотя, поскольку MinGW компилирует и связывает одну команду, возможно, вы тоже получаете оптимизацию.) –

+0

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

+0

Это хорошее решение. Но я действительно думаю, что путь для Windows с mingw для создания DLL уродлив. – Jimmy