Сборка библиотеки DLL с помощью gcc с использованием библиотечного файла (.a), преобразованного из библиотеки импорта (.lib)

Шаг 1. У меня есть импорт файла lib (main.lib) для моего исполняемого файла (main.exe) который экспортирует некоторые символы. Эти символы экспортируются с использованием extern «C».

Шаг 2. У меня тоже есть исходный файл (extra.cpp) который экспортирует некоторые дополнительные функции. Я генерирую статическую библиотеку ссылок (extra.lib) из него и включаю main.lib в него, так как эти дополнительные функции являются пользователями экспорта из main.exe.

Шаг 3. Длл (bbb.dll) встроено связывание с этой библиотекой (extra.lib) для вызова этих дополнительных функций из main.exe.
(Обратите внимание, что bbb.dll загружается и используется main.exe На первом месте.)

Теперь я пытаюсь повторить шаги 2 и 3, используя Mingw (gcc) вместо MS Visual Studio (cl). Давайте назовем это Шаг 2x и 3x.
Поскольку main.exe — это большой проект с большим количеством файлов … здание libmain.a из источников не хороший вариант, я нашел Вот тот main.lib можно преобразовать в файл .a с помощью следующих команд:

reimp -d main.lib
dlltool -k -d main.def -l libmain.a
# reimp creates the .def file.
# dlltool uses the .def to create the .a that is linked in to the app.

Шаг 2х.

gcc -c -o extra.o -O1 -s -x c++ extra.cpp
ar rs libextra.a extra.o
ar rs libextra.a libmain.a

Шаг 3х.

g++ -O2 -o bbb.dll -shared -x c++ bbb.cpp  -static-libgcc -static-libstdc++  -Wl,-s -Wl,--kill-at,--export-all-symbols,--enable-stdcall-fixup -Wl,--large-address-aware -lextra

Я получаю ошибки компоновщика на шаге 3x.

libmain.a(lextra.o):extra.cpp:(.text+0x38): undefined reference to `A_Function_In_main'

Это проблема искажения имени?

Или вообще возможно построить bbb.dll используя gcc таким образом?

Что я делаю не так?

Я использую Visual Studio 2012 на Windows 7. MinGW с gcc 4.6.1.

Проверка, находится ли A_Function_In_main в libmain.a:

nm libmain.a > libmain_dump.txt

Блок текста в libmain_dump.txt относительно ‘A_Function_In_main’

dshms00350.o:
00000000 b .bss
00000000 d .data
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
00000000 T A_Function_In_main
00000000 I __imp_A_Function_In_main
U _head_libmain_a

0

Решение

Есть ли способ упростить этот вопрос?

Хотя кажется, что между большой основной программой и дополнительной DLL существует некоторая циклическая зависимость, я предполагаю, что вы просто используете функцию обратного вызова в main. Моим усилиям мешает отсутствие исходного кода или тех же версий MSVC и gcc, которые вы используете. (У меня MS Visual Studio 2010 и mingw gcc-4.7.2) Но суть проблемы, похоже, заключается в преобразовании сгенерированной MS библиотеки импорта для работы с gcc.

В качестве альтернативы вы можете реализовать собственную библиотеку импорта, вызвав LoadLibrary («bbb.dll»), а затем использовать GetProcAddress («A_Function_In_Main»). Но я предполагаю, что ваш реальный проект делает этот подход слишком дорогим.

В качестве диагностики протестируйте библиотеку импорта reimp с помощью более простого тестового стенда:

foo.h

#ifdef FOO_DLL_EXPORTS
#define FOO_DLL_API __declspec(dllexport)
#else
#define FOO_DLL_API __declspec(dllimport)
#endif

extern "C" int FOO_DLL_API foo (int x);

foo.cpp

// define FOO_DLL_EXPORTS when building foo.cpp

#include "foo.h"#include <iostream>
using std::cout;
using std::endl;

extern "C" int FOO_DLL_API foo (int x)
{
return x + 1;
}
int main()
{
cout << "foo.exe foo(1) returns " << foo(1) << endl; // expect 2
return 0;
}

test.cpp

#include "foo.h"#include <iostream>
using std::cout;
using std::endl;

int main()
{
cout << "test.exe foo(3) returns " << foo(3) << endl; // expect 4
return 0;
}

Используйте MSVC для компиляции foo.cpp в foo.exe и импорта библиотеки foo.lib.

# compile foo.cpp; define FOO_DLL_EXPORTS
/ZI /nologo /W3 /WX- /Od /Oy- /D "FOO_DLL_EXPORTS" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\foo.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /errorReport:queue
# linker; generate foo.lib
/OUT:"C:\svn_local\0\Users\mku\MinGW_w32\stackoverflow.com\20484904\trunk\msvc2010_build_foo_exe\foo\Debug\foo.exe" /INCREMENTAL /NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Debug\foo.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\svn_local\0\Users\mku\MinGW_w32\stackoverflow.com\20484904\trunk\msvc2010_build_foo_exe\foo\Debug\foo.pdb" /SUBSYSTEM:CONSOLE /PGD:"C:\svn_local\0\Users\mku\MinGW_w32\stackoverflow.com\20484904\trunk\msvc2010_build_foo_exe\foo\Debug\foo.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"foo.lib" /MACHINE:X86 /ERRORREPORT:QUEUE

Убедитесь, что нет ошибок компиляции / ссылки.
Убедитесь, что код возврата foo.exe равен 2, как и ожидалось.

Используйте mingw-utils reimp для преобразования foo.lib в libfoo.a для использования с gcc. (Предполагая, что реальный foo.cpp нецелесообразно перестраивать, хотя в этом небольшом примере foo.cpp можно перестроить с помощью gcc-4.7.2)

reimp -d foo.lib
# reimp creates the foo.def file.
dlltool -k -d foo.def -l libfoo.a
# dlltool uses the .def to create the .a that is linked in to the app.

Убедитесь, что libfoo.a содержит __imp_foo.

nm libfoo.a | grep __imp_foo

00000000 I __imp__foo

Используйте gcc для компиляции test.cpp для test.exe с библиотекой импорта libfoo.a.

g++.exe test.o  -o test.exe -static -static-libgcc -static-libstdc++ -L"C:/MinGW/lib"  /MinGW/lib/gcc/mingw32/4.7.2/libstdc++.a /MinGW/lib/gcc/mingw32/4.7.2/libgcc.a  libfoo.a

Убедитесь, что нет ошибок компиляции / ссылки.
Убедитесь, что код возврата test.exe равен 4, как и ожидалось.

Это работает в моей системе.

Microsoft Visual Studio 2010 Версия 10.0.40219.1 SP1Rel.

gcc 4.7.2

переоснащать источники из http://sourceforge.net/p/mingw/utils/ci/master/tree/reimp/

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]