2013-12-10 16 views
0

1 단계 내 실행 파일의 가져 오기 LIB 파일 (main.lib) (주 있습니다. exe)는 일부 기호를 내 보냅니다. 이러한 기호는 extern "C"를 사용하여 내 보냅니다.라이브러리 파일 (.A)를 사용하여 GCC와 DLL을 빌드는 가져 오기 라이브러리로 변환 (lib 디렉토리)

2 단계는 또한 몇 가지 추가 기능을 수출 소스 파일 (extra.cpp)가 있습니다. 정적 연결 라이브러리 (extra.lib)를 생성하고 main.exe의 내보내기 사용자 인 추가 함수가 있으므로 main.lib을 포함시킵니다.

3 단계는 DLL이 ( bbb.dll) 메인 .exe에서 그 여분의 함수를 호출하는이 라이브러리 (extra.lib)와 연결 내장되어 있습니다. (bbb.dll로드와 처음에 메인 .exe에 의해 사용되는 점에 유의.)

가 이제와 Mingw (GCC)를 사용하여 2 단계와 3 단계를 반복하기 위해 노력하고있어 대신 MS의 Visual Studio (cl). Step 2x와 3x라고 부르 자. main.exe가 많은 파일을 가진 큰 프로젝트이기 때문에 ... libmain.a 소스가 좋은 옵션이 아니므로 here이라는 메시지가 표시됩니다. 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 

나는 단계 3 배에서 링커 오류를 받고 있어요.

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

이름 차이 차이는 무엇입니까?

또는 gcc가이 방법을 사용하여 bbb.dll 을 구축하는 것도 가능하다?

내가 뭘 잘못 했니?

Windows 7에서 Visual Studio 2012를 사용하고 있습니다. MinGW with 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

에서

GCC 4.7.2

reimp 소스? – sny

+1

확인을 위해 dumpbin/export bbb.dll (Visual Studio 도구 명령 프롬프트에서)이 dll의 진입 점을 나열합니다. DLL은 모든 컴파일러에서 작동해야하기 때문에 DLL 이름을 절대로 이름을 변경해서는 안됩니다 ("C"각 함수를 내 보내야한다고 말한 적이 있습니다). – MarkU

+0

하지만 실제 문제는 링크 단계에서 실패한 MinGW를 사용하여 bbb.dll을 작성하는 것입니다. – MarkU

답변

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인지 확인하십시오.

foo.lib를 gf와 함께 사용하기 위해 libfoo.a로 변환하려면 mingw-utils reimp를 사용하십시오.

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가 포함되어 있는지 확인 (이 작은 예에 foo.cpp에 GCC-4.7.2으로 재 구축 할 수 있지만, 실제 foo.cpp의 재구성을 비실용적이었다 가정).

nm libfoo.a | grep __imp_foo 

00000000 I __imp__foo 

gcc를 사용하여 가져 오기 라이브러리 libfoo.a로 test.cpp를 test.exe로 컴파일하십시오.

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. 나는 내 보낸 어떤 이름을 찾기 위해 사용하고 그들이 엉망이 얼마나 수있는 도구 http://sourceforge.net/p/mingw/utils/ci/master/tree/reimp/