使用 linux 编译 __stdcall 动态库时,取消@ 的符号结尾

在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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值