浅析VC++或MinGW—GCC的动态链接库转为C++ Builder动态链接库的实现过程
2015-09-11蒋子威赵磊唐飞琳
蒋子威++赵磊++唐飞琳
摘要:通过对C++builder与VC++、MinGW_GCC动态链接库函数的分析,找出了它们之间的区别所在,然后针对其不同,给出了实现其转化的实现过程。
关键词:动态链接库;转化;实现过程
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)17-0062-00
VC++ or MinGW-GCC Dynamic Link Library to C++ Builder Dynamic Link Library Implementation Process
JIANG Zi-wei1, ZHAO Lei2, TANG Fei-lin2
(1.Workers University of Guilin,Guilin 541002,China;2.Guilin Pilot Software Development Co., Ltd.Guilin 541004,China)
Abstract:Through the analysis of C++builder and VC++, MinGW_GCC dynamic link library function, the differences between them are found out, and then the realization of the transformation is given.
Key words: dynamic link library; implementation process; method
1 概述
国内物联网软件的开发一般是基于硬件设备生产厂家提供的SDK程序开发包而开发,由于绝大部分硬件设备厂家提供的SDK程序开发包都是用VC++或MinGW-GCC编译而成,另一方面网络上发布的大多数开源软件代码一般也是符合MinGW-GCC编译器的编译要求,MinGW-GCC编译器的编译动态链接库可以直接为VC++使用,因此导致了国内大部分的物联网软件都是用VC++开发而成。但在现在的社会需求中开发管理软件,需要对大量数据的处理与存储,特别是物联网管理软件的设计。如果采用VC++语言开发,那将对大量数据的处理带来极大的不便,为开发具有强大数据管理功能的管理软件,人们不得不采用在数据库处理上具有大家公认的、独特优势的Embarcadero公司产品--C++builder,采用C++builder开发管理软件的公司数量远远超过采用微软的VC++开发的数量。虽然硬件设备厂家提供的SDK开发包是用VC++或MinGW-GCC编译的,但又不能直接为C++builder开发平台语言所使用,究其原因主要是其动态链接库函数不能为C++builder语言所接受,在借助硬件设备厂家的SDK程序开发包的同时,如何才能突破这一瓶颈,更好地采用具有独具匠心的C++builder开发语言平台设计出更优的管理软件?
2 C++builder与VC++、MinGW-GCC动态链接库函数的区别
基于Windows平台下开发设计的VC++语言、C++语言或者C++builder语言等都会隐式地使用动态链接库所需要的三个文件,即头文件(*.h)、动态链接库文件(*.dll)、引入库文件(*.lib),三者缺一不可。默认情况下,VC++与MinGW-GCC二者在编译和使用动态链接库都是一样的,可以通用;但C++builder却不能使用VC++或者MinGW-GCC产生的引入库文件(*.lib),分析其原因有其两点:一是C++builder引入库与VC++ 、MinGW-GCC引入库二进制格式不一样,因而导致它们之间不兼容;见表1所示。
表1 引入库文件(*.lib)的二进制格式
[VC++、MinGW-GCC格式\&C++builder格式\&COFF\&OMF\&]
二是C++builder对函数的名字修饰与VC++、MinGW-GCC对函数的名字修饰不一致。如表2所示。
表2 不同调用方式的名字修饰
[调用方式\&头文件中的函数名\&VC++\MinGW-GCC函数命名\&C++builder的函数命名\&__stdcall\&MyFunction\&_MyFunction@nn
(nn--数字)\&MyFunction\&__cdecl\&MyFunction\&MyFunction\&_MyFunction\&__fastcall\&MyFunction\&@MyFunction@nn
(nn--数字)\&@MyFunction\&]
3 实现过程与方法
根据上面的分析,我们可以将VC++、MinGW-GCC编译的动态链接库转换为C++builder能调用的实现过程与方法归结为以下两点:
3.1 将VC++、MinGW-GCC编译的动态链接库转换为C++builder能识别的库的实现过程
1)检查*.h文件中函数调用方式;
2)利用tdump.exe从*.dll中导出函数名称列表*.lst,并检查*.dll中的函数名称与*.h中的函数名称是不是一致;
3)若*.dll中的函数名称与*.h中的函数名称一样,并且其调用方式为__stdcall,则使用工具coff2omf.exe将适合VC++、MinGW-GCC的*.lib转换为适合C++builder的*.lib或使用工具implib.exe直接从*.dll中生成适合C++builder的*.lib;
4)若*.dll中的函数名称与*.h中的函数名称一样,并且调用方式为__cdecl;若*.dll中的函数名称与*.h中的函数名称不一样,并且调用方式为__stdcall.使用工具impdef.exe从*.dll中生成*.def,用文本编辑软件按照C++builder的函数名称的修饰要求设置别名文件*.def,最后使用工具implib.exe和函数别名文件*.def从*.dll中生成*.lib。
3.2 生成C++builder动态链接库的具体方法
3.2.1 __cdecl调用格式的*.lib生成
1)使用如下命令生成函数名称列表*.lst
Tdump.exe –m –ee MyDll.dll>MyDll.lst
其中MyDll.dll是动态链接库名称,MyDll.lst是函数名称列表,可用文本编辑器打开。
2)用文本编辑器打开MyDll.lst和*.h,检查*.dll中的函数名称是不是与*.h的函数名称一样。
3)若*.dll中的函数名称与*.h中的函数名称一样,使用如下命令导出*.def文件:
Impdef.exe mydll.def mydll.dll
按下列格式用文本编辑器编辑与C++builder兼容的别名文件*.def:
LIBRARY MyDll.DLL
EXPORTS
_函数名1 = 函数名1
_函数名2 = 函数名2
最后用如下命令生成*.lib:
Implib mydll.lib mydll.def mydll.dll
3.2.2 __stdcall调用格式的*.lib生成
1)使用如下命令生成函数名称列表*.lst
Tdump.exe –m –ee MyDll.dll>MyDll.lst
其中MyDll.dll是动态链接库名称,MyDll.lst是函数名称列表,可用文本编辑器打开。
2)用文本编辑器打开MyDll.lst和*.h,检查*.dll中的函数名称是不是与*.h的函数名称一样。
3)若*.dll中的函数名称与*.h中的函数名称一样,使用如下命令生成*.lib文件:
Coff2omf.exe –lib:st inputlib outputlib
或使用如下命令生成*.lib:
Implib.exe mydll.lib mydll.dll
4)若*.dll中的函数名称与*.h中的函数名称不一样,使用如下命令导出*.def文件:
Impdef.exe mydll.def mydll.dll
按下列格式用文本编辑器编辑与C++builder兼容的别名文件*.def:
LIBRARY MyDll.DLL
EXPORTS
函数名1 = _函数名1@nn1
函数名2 = _函数名2@nn2
最后用如下命令生成*.lib:
Implib mydll.lib mydll.def mydll.dll
下面是国内几个物联网品牌的SDK开发包在C++builder中的具体应用
1)海康安防监控SDK开发包
根据海康安防监控SDK开发包的HCNetSDK.h可以知道其函数是采用__stdcall调用方式的,用tdump.exe查看HCNetSDK.dll中的函数名与的HCNetSDK.h中的函数名一样,因此可以直接用如下命令生成适合C++builder使用的HCNetSDK.lib:
Implib HCNetSDK.lib HCNetSDK.dll
2)大华安防监控SDK开发包
根据大华安防监控SDK开发包的dhnetsdk.h可以知道其函数是采用__stdcall调用方式的,用tdump.exe查看dhnetsdk.dll中的函数名与dhnetsdk.h中的函数名一样,因此可以直接用如下命令生成适合C++builder使用的dhnetsdk.lib:
Implib dhnetsdk.lib dhnetsdk.dll
3)华迈安防监控SDK开发包
根据华迈安防监控SDK开发包的hm_sdk.h可以知道其函数是采用__cdecl调用方式的,用tdump.exe查看hmsdk.dll中的函数名与的hm_sdk.h中的函数名一样,使用如下命令导出*.def文件:
Impdef.exe hmsdk.def hmsdk.dll
按下列格式用文本编辑器编辑与C++builder兼容的别名文件hmsdk.def:
LIBRARY HMSDK.DLL
EXPORTS
_hm_audio_capture_init = hm_audio_capture_init
_hm_audio_capture_set_callback = hm_audio_capture_set_callback
_hm_audio_capture_start = hm_audio_capture_start
_hm_audio_capture_stop = hm_audio_capture_stop
_hm_audio_capture_uninit = hm_audio_capture_uninit
_hm_audio_decode = hm_audio_decode
_hm_audio_encode = hm_audio_encode
最后用如下命令生成hmsdk.lib:
Implib hmsdk.lib hmsdk.def hmsdk.dll
4 结束语
实践证明,只要按照上述方法与步骤,就能将VC++、MINGW-GCC编译链接的动态库转换为C++builder能接受处理的动态链接库,并能如心所愿地开发出所要的具有强大数据处理功能的物联网管理软件,本文的方法可以为同行者开发强大数据管理功能的物联网软件提供有益的借鉴。
参考文献:
[1] 陆卫忠, 刘文亮. C++Builder 6程序设计教程[M]. 2版. 北京: 科学出版社, 2000.
[2] Herbert Schildt, Greg Guntle. C++builder技术大全[M]. 周海斌,译. 北京: 机械工业出版社, 2002.
[3] Ivor Horton. Visual C++ 2013入门经典[M]. 李周芳, 江凌 译. 7版. 北京: 清华大学出版社, 2013.
[4] 湛为芳. 高效实用Visual C++库函数设计[M]. 北京: 清华大学出版社, 2010.