cygwin下把window下dll文件转换成a或者so文件的方法
2012-04-21 23:14
218 查看
转载请注明出处: http://blog.csdn.net/nana08/article/details/7374635
总所周知,cygwin只是linux、unix在window下的一个模拟环境。其中cygwin下的一个重要组件cygwin1.dll提供了window下感觉linux的一个posix接口。说白了,在window下只能使用linux下一些与硬件无关的命令,如ls、pwd等,因为他们都在cygwin1.的dll中实现了,但是与平台相关的函数就没有办法啦,例如iptables命令。iptables命令在cygwin下无法使用。
有时候在做平台移植的时候,例如一个linux下的一个程序移植到window下,使用cygwin可以帮助我们省好多精力。但是问题也随之而来,如果你的程序中包含于平台相关的数据结构,与平台先关的函数、或者与平台相关的库文件,在做移植的时候就会出现问题。
例如,一个linux程序A,在代码中使用了linux平台下的libpcap,相应的,在cygwin下做移植的时候,就需要用到winpcap,就需要在cygwin下安装winpcap库,但是cygwin是类linux环境,所以只能用.a或者.so文件,所以就需要把winpcap编程成cygwin可以识别的.a或者.so文件。
以后,在遇到与平台有关的linux程序移植到windows平台的时候,就需要把程序中所用到的库文件由linux版本换成window版本,而且需要的window版本不能是.,lib或者.dll
的形式,必须转或者cygwin所能识别的.a 或者.so版本。
ygwin的gcc编译器使用windows的dll文件一般的步骤是使用pexports或dumpbin程序导出dll的DEF文件
其中dumpbin导出的DEF文件需要手动修改,所以推荐使用pexports,做法如下:
pexports libFedTimed.dll > libFedTimed.def
dlltool -D libFedTimed.dll -d libFedTimed.def-l libFedTimed.a -k
如果该dll是C的函数库,如libmysql.dll或者kernel32.dll类的DLL,这样做就一点问题没有,直接使用。
但是如果是VC6、VC7生成的C++库则存在C/C++ 轧名规则(name mangling)问题,参见如下表
Compiler void h(int) void h (int, char)void h(void)
GNU GCC 3.x _Z1hi _Z1hic _Z1hv
GNU GCC 2.9x h__Fi h__Fic h__Fv
Intel C++ 8.0 for Linux _Z1hi _Z1hic _Z1hv
Microsoft VC++ v6/v7 ?h@@YAXH@Z ?h@@YAXHD@Z?h@@YAXXZ
Borland C++v3.1 @h$qi @h$qizc @h$qv
OpenVMS C++ V6.5 (ARM mode) H__XI H__XICH__XV
OpenVMS C++ V6.5 (ANSI mode)CXX$__7H__FI0ARG51T CXX$__7H__FIC26CDH77 CXX$__7H__FV2CB06E8
OpenVMS C++ X7.1 IA-64 CXX$_Z1HI2DSQ26A CXX$_Z1HIC2NP3LI4 CXX$_Z1HV0BCA19V
Digital MarsC++ ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
SunPro CC __1cBh6Fi_v_ __1cBh6Fic_v_ __1cBh6F_v_
HP aC++ A.05.55IA-64 _Z1hi _Z1hic _Z1hv
HP aC++ A.03.45PA-RISC h__Fi h__Fic h__Fv
Tru64 C++V6.5 (ARM mode) h__Xi h__Xic h__Xv
Tru64 C++V6.5 (ANSI mode) __7h__Fi __7h__Fic __7h__Fv
不同编译器生成的导出名称不同,所以在使用Cygwin的gcc编译器链接libFedTimed.a时会出现
undefinedreference to `RTI::FedTimeFactory::makeZero()' tstDMSORti HelloWorld.cpp line442 1225384733078 5683
错误
因为gcc编译对RTIfedTime::getTime()翻译为:_ZN3RTI14FedTimeFactory8makeZeroEv
而DMSO RTI的libFedTimed.dll提供的是:?makeZero@FedTimeFactory@RTI
通过自己的摸索,可以修改libFedTimed.def文件中的导出函数声明为:
_ZN3RTI14FedTimeFactory8makeZeroEv=?makeZero@FedTimeFactory@RTI
再使用dlltool -DlibFedTimed.dll -d libFedTimed.def -l libFedTimed.a -k生成的.a文件就可以使用了。
这里还有一个小技巧:
先将你的源程序编译出来的.o文件使用nm -s Country.o > fungcc3.txt得到针对函数的gcc命名_ZN3RTI14FedTimeFactory8makeZeroEv,但是它不容易分辨出来,再使用c++filt提出可阅读的的函数调用名称
cat fungcc3.txt | c++filt > fungcc3read.txt
针对VC生成的.def文件,同样可以使用undname恢复函数名称
undname libFedTimed.def > funvcread.txt
然后对照fungcc3.txt、fungcc3read.txt、libFedTimed.def、funvcread.txt就可以完成轧名规则的变换。
总所周知,cygwin只是linux、unix在window下的一个模拟环境。其中cygwin下的一个重要组件cygwin1.dll提供了window下感觉linux的一个posix接口。说白了,在window下只能使用linux下一些与硬件无关的命令,如ls、pwd等,因为他们都在cygwin1.的dll中实现了,但是与平台相关的函数就没有办法啦,例如iptables命令。iptables命令在cygwin下无法使用。
有时候在做平台移植的时候,例如一个linux下的一个程序移植到window下,使用cygwin可以帮助我们省好多精力。但是问题也随之而来,如果你的程序中包含于平台相关的数据结构,与平台先关的函数、或者与平台相关的库文件,在做移植的时候就会出现问题。
例如,一个linux程序A,在代码中使用了linux平台下的libpcap,相应的,在cygwin下做移植的时候,就需要用到winpcap,就需要在cygwin下安装winpcap库,但是cygwin是类linux环境,所以只能用.a或者.so文件,所以就需要把winpcap编程成cygwin可以识别的.a或者.so文件。
以后,在遇到与平台有关的linux程序移植到windows平台的时候,就需要把程序中所用到的库文件由linux版本换成window版本,而且需要的window版本不能是.,lib或者.dll
的形式,必须转或者cygwin所能识别的.a 或者.so版本。
ygwin的gcc编译器使用windows的dll文件一般的步骤是使用pexports或dumpbin程序导出dll的DEF文件
其中dumpbin导出的DEF文件需要手动修改,所以推荐使用pexports,做法如下:
pexports libFedTimed.dll > libFedTimed.def
dlltool -D libFedTimed.dll -d libFedTimed.def-l libFedTimed.a -k
如果该dll是C的函数库,如libmysql.dll或者kernel32.dll类的DLL,这样做就一点问题没有,直接使用。
但是如果是VC6、VC7生成的C++库则存在C/C++ 轧名规则(name mangling)问题,参见如下表
Compiler void h(int) void h (int, char)void h(void)
GNU GCC 3.x _Z1hi _Z1hic _Z1hv
GNU GCC 2.9x h__Fi h__Fic h__Fv
Intel C++ 8.0 for Linux _Z1hi _Z1hic _Z1hv
Microsoft VC++ v6/v7 ?h@@YAXH@Z ?h@@YAXHD@Z?h@@YAXXZ
Borland C++v3.1 @h$qi @h$qizc @h$qv
OpenVMS C++ V6.5 (ARM mode) H__XI H__XICH__XV
OpenVMS C++ V6.5 (ANSI mode)CXX$__7H__FI0ARG51T CXX$__7H__FIC26CDH77 CXX$__7H__FV2CB06E8
OpenVMS C++ X7.1 IA-64 CXX$_Z1HI2DSQ26A CXX$_Z1HIC2NP3LI4 CXX$_Z1HV0BCA19V
Digital MarsC++ ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
SunPro CC __1cBh6Fi_v_ __1cBh6Fic_v_ __1cBh6F_v_
HP aC++ A.05.55IA-64 _Z1hi _Z1hic _Z1hv
HP aC++ A.03.45PA-RISC h__Fi h__Fic h__Fv
Tru64 C++V6.5 (ARM mode) h__Xi h__Xic h__Xv
Tru64 C++V6.5 (ANSI mode) __7h__Fi __7h__Fic __7h__Fv
不同编译器生成的导出名称不同,所以在使用Cygwin的gcc编译器链接libFedTimed.a时会出现
undefinedreference to `RTI::FedTimeFactory::makeZero()' tstDMSORti HelloWorld.cpp line442 1225384733078 5683
错误
因为gcc编译对RTIfedTime::getTime()翻译为:_ZN3RTI14FedTimeFactory8makeZeroEv
而DMSO RTI的libFedTimed.dll提供的是:?makeZero@FedTimeFactory@RTI
通过自己的摸索,可以修改libFedTimed.def文件中的导出函数声明为:
_ZN3RTI14FedTimeFactory8makeZeroEv=?makeZero@FedTimeFactory@RTI
再使用dlltool -DlibFedTimed.dll -d libFedTimed.def -l libFedTimed.a -k生成的.a文件就可以使用了。
这里还有一个小技巧:
先将你的源程序编译出来的.o文件使用nm -s Country.o > fungcc3.txt得到针对函数的gcc命名_ZN3RTI14FedTimeFactory8makeZeroEv,但是它不容易分辨出来,再使用c++filt提出可阅读的的函数调用名称
cat fungcc3.txt | c++filt > fungcc3read.txt
针对VC生成的.def文件,同样可以使用undname恢复函数名称
undname libFedTimed.def > funvcread.txt
然后对照fungcc3.txt、fungcc3read.txt、libFedTimed.def、funvcread.txt就可以完成轧名规则的变换。
相关文章推荐
- cygwin跨平台移植开发系列2--so2lib实用工具(把cygwin生成的so或dll转换成vc可调用的lib)
- Java之—— JAVA Web项目中DLL/SO文件动态加载方法
- Window下分解pfx证书文件转换成pem文件的命令行方法
- mpi编译Boost生成so文件出错:failed gcc.link.dll解决方法
- Solaris编译Boost生成so文件出错:failed gcc.link.dll解决方法
- 利用python调用外部的dll或者so文件,碉堡了
- 解决window.location.href下载apk文件会自动转换成zip文件方法
- 利用datawindow或者datastore的saveas方法导出excell文件,然后修改中文表头
- Java框架JNA调用C方法(windows链接库dll文件、linux链接库so文件)
- 使用VS2008创建一个DLL文件的方法
- 把其他类型的DLL文件转换为C++的DLL文件
- 物理路径,虚拟路径,物理路径与虚拟路径转换,文件下载方法
- Android Studio中配置so文件的方法
- Android Studio 导入 SO 文件方法示例
- 一种强行指定dll assembly读取其相应*.dll.config配置文件的方法(又名:如何创建.net 的DCOM)
- 通过silktest调用c#写的工具获取dll文件信息的方法
- AndroidStudio-加载so文件与jar包(可能是最完美的解决方法)
- 盘点PDF文件转Word文档的四种高效率转换方法
- php使用curl模拟浏览器表单上传文件或者图片的方法
- window下使用直接复制数据库文件方式复制数据库和表的方法