在Linux下,编译生成动态链接库时,可以增加gcc编译选项 -Wl,--kill-at来取消@后缀。
在windows 的vc++下,可增加 .def文件来解决。
Build DLLs with MinGW(–kill-at)
Problem: As using link option --kill-at, the symbols of functions in DLL file is without '@x' when using
__stdcall. But the objects linking to the library still ask for symbols with '@x'.
The solution is to reproduce the implib bridging the linking symbols with and without '@x'.
1. Using attribute __stdcall.<br />
2. Using link option --kill-at.<br />
3. Using .def file and dlltool to recreate the proper implib.
Function definition:
#ifdef BUILD_DLL<br />
#define EXPORT __declspec(dllexport)<br />
#else<br />
#define EXPORT __declspec(dllimport)<br />
#endif<br />
#ifdef BUILD_EXE<br />
#undef EXPORT<br />
#define EXPORT<br />
#endif<br />
#ifndef U_SYS_H<br />
#define U_SYS_H<br />
/* Set up for C function definitions, even when using C++ */<br />
#ifdef __cplusplus<br />
extern "C" {<br />
#endif<br />
//<br />
#define INFO_BUFFER_SIZE 32767<br />
#define VOLUME_SERIAL_LENGTH 10<br />
#define XP_KEY_LENGTH 30<br />
#define OS_NAME_LENGTH 20<br />
// Message<br />
EXPORT void __stdcall showMsg(const char *szMsg, const char *szTitle="Info");<br />
//<br />
EXPORT void __stdcall showError(const char *msg);<br />
EXPORT void __stdcall showErrorInfo(DWORD eNum);<br />
// Volume Information<br />
//<br />
EXPORT void __stdcall getVolSerialNum(char *sn, const char *vol = "C://");<br />
//<br />
EXPORT int __stdcall getVolumeList(char *vlmList);<br />
// XP cdkey<br />
EXPORT void __stdcall getXPKey(char *cdkey);<br />
// User Info<br />
EXPORT void __stdcall getComputerName(char *hostname);<br />
//<br />
EXPORT void __stdcall getOSVersion(char *osver);<br />
EXPORT void __stdcall getOSName(char *osname);<br />
//<br />
EXPORT void __stdcall getMacAddress(char *macAddr);<br />
EXPORT int __stdcall getAdapterNum();<br />
//<br />
EXPORT int __stdcall getUserName(char *uname);<br />
// Monitor<br />
EXPORT int __stdcall turnOffMonitor(HWND hwnd);<br />
EXPORT int __stdcall turnOnMonitor(HWND hwnd);<br />
EXPORT int __stdcall showScreenSave(HWND hwnd);<br />
EXPORT int __stdcall showStartMenu(HWND hwnd);<br />
EXPORT int __stdcall shutdownWindows();<br />
//<br />
EXPORT int __stdcall addIcon2Desktop();<br />
EXPORT int __stdcall addIcon2MyComputer();<br />
/* Ends C function definitions when using C++ */<br />
#ifdef __cplusplus<br />
}<br />
#endif<br />
#endif // U_SYS_H<br />
Build DLL and create DEF file.
g++ -c -fPIC -O2 -DBUILD_DLL usys.cpp -o usys.o<br />
g++ -shared -o libusys.dll usys.o -Wl,--kill-at,--output-def,libusys.def,--out-implib,libusys.a -mwindows -lnetapi32
The DEF file:
EXPORTS<br />
addIcon2Desktop = addIcon2Desktop@0 @1<br />
addIcon2MyComputer = addIcon2MyComputer@0 @2<br />
getAdapterNum = getAdapterNum@0 @3<br />
getComputerName = getComputerName@4 @4<br />
getMacAddress = getMacAddress@4 @5<br />
getOSName = getOSName@4 @6<br />
getOSVersion = getOSVersion@4 @7<br />
getUserName = getUserName@4 @8<br />
getVolSerialNum = getVolSerialNum@8 @9<br />
getVolumeList = getVolumeList@4 @10<br />
getXPKey = getXPKey@4 @11<br />
showError = showError@4 @12<br />
showErrorInfo = showErrorInfo@4 @13<br />
showMsg = showMsg@8 @14<br />
showScreenSave = showScreenSave@4 @15<br />
showStartMenu = showStartMenu@4 @16<br />
shutdownWindows = shutdownWindows@0 @17<br />
turnOffMonitor = turnOffMonitor@4 @18<br />
turnOnMonitor = turnOnMonitor@4 @19
Delete unnecessary symbols.
EXPORTS<br />
addIcon2Desktop@0 @1<br />
addIcon2MyComputer@0 @2<br />
getAdapterNum@0 @3<br />
getComputerName@4 @4<br />
getMacAddress@4 @5<br />
getOSName@4 @6<br />
getOSVersion@4 @7<br />
getUserName@4 @8<br />
getVolSerialNum@8 @9<br />
getVolumeList@4 @10<br />
getXPKey@4 @11<br />
showError@4 @12<br />
showErrorInfo@4 @13<br />
showMsg@8 @14<br />
showScreenSave@4 @15<br />
showStartMenu@4 @16<br />
sshutdownWindows@0 @17<br />
turnOffMonitor@4 @18<br />
turnOnMonitor@4 @19
Create new implib.
dlltool -d libusysx.def --dllname libusys.dll --output-lib libusys.a --kill-at<br />
g++ -c test_dll.cpp -o test_dll.o<br />
g++ -o test_dll.exe test_dll.o -mwindows -lusys -L.
Symbols in object file.
00000000 b .bss<br />
00000000 d .data<br />
00000000 r .eh_frame<br />
00000000 r .rdata<br />
00000000 t .text<br />
00000000 T _WinMain@16<br />
U ___gxx_personality_v0<br />
U __alloca<br />
U __imp__getAdapterNum@0<br />
U __imp__getComputerName@4<br />
U __imp__getMacAddress@4<br />
U __imp__getOSName@4<br />
U __imp__getOSVersion@4<br />
U __imp__getUserName@4<br />
U __imp__getVolSerialNum@8<br />
U __imp__getXPKey@4<br />
U __imp__showMsg@8<br />
U _wsprintfA
编译 freeglut.dll 的脚本:
1 @echo off
2
3
4 gcc -fPIC -c ./freeglut-2.6.0/src/*.c -D__MINGW32__ -DFREEGLUT_EXPORTS /
-I./freeglut-2.6.0/include -I./freeglut -2.6.0/src -I./freeglut-2.6.0/include/GL
5
6 gcc -shared -o freeglut.dll *.o /
-Wl,--output-def,freeglut_origin.def,--out-implib,freeglut.dll.a,--kill-at -mwindows -lopengl32 -lglu32 -lwinmm
7
8 sed "s/glut.*/ =//g" freeglut_origin.def > freeglut.def
9
10 dlltool -d freeglut.def --dllname freeglut.dll --output-lib libfreeglut.dll.a --kill-at--
11
12 gcc -c freeglut-2.6.0/progs/demos/shapes/shapes.c -I./freeglut-2.6.0/include /
-I./freeglut-2.6.0/src -I./freegl ut-2.6.0/include/GL
13
14 gcc -o shapes.exe shapes.o -L. -lfreeglut -lopengl -mwindows
15
16 @pause