c++builder调用VC的dll以及VC调用c++builder的dll

转载 2007年09月12日 01:07:00

解析__cdecl,__fastcall, __stdcall 的不同:
在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。
比如说__cdecl,它是标准的c方法的堆栈调用方式,就是在函数调用时的参数压入堆栈是与函数的声明顺序相反的,其它两个可以看MSDN,不过这个对我们编程没有太大的作用
---------------------------------------------------------------
调用约定
调用约定(Calling convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:
_cdecl
按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于"C"函数或者变量,修饰名是在函数名前加下划线。对于"C++"函数,有所不同。
如函数void test(void)的修饰名是_test;对于不属于一个类的"C++"全局函数,修饰名是_test@@ZAXXZ(怎么感觉像乱码??)。
这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。
_stdcall
按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于"C"函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号"@"及参数的字节数,如函数int func(int a, double b)的修饰名是_func@12。对于"C++"函数,则有所不同。所有的Win32 API函数都遵循该约定。
_fastcall
头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于"C"函数或者变量,修饰名以"@"为前缀,然后是函数名,接着是符号"@"及参数的字节数,如函数int func(int a, double b)的修饰名是@func@12。对于"C++"函数,有所不同。
未来的编译器可能使用不同的寄存器来存放参数。

Dll中用 __declspec(dllexport)声明的函数:
__declspec(dllexport)只是表示这个函数是一个DLL导出函数,而__stdcall是一种函数调用约定,两者应该是没有冲突的.   
如:__declspec(dllexport)  void  __stdcall  aTry();

c++builder和vc描述符定义的区别
在c++builder中
        __cdecl的函数输出前会带:"_"
        __stdcall无特征,只输出函数名
        __fastcall函数输出前带:"@"
        都无"@nn"后缀格式!
在vc中
        __cdecl无特征,只输出函数名
        __stdcall的函数输出前会带:"_"后缀带:"@nn"
        __fastcall函数输出前带:"@"后缀带:"@nn

c++builder调用VC的dll:
在VC中编写DLL时,使用了.def文件,在出口函数声明时也在前面加上了__declspec(dllexport)说明。把VC生成的DLL文件放在了当前目录下,使用BCB的命令行工具implib生成的.lib文件,具体格式为implib bcb.lib vc.dll,再把implib根据dll生成的LIB文件加入到工程中,再在工程中加入DLL出口函数的声明(函数名前加上了WINAPI,即__stdcall;每个函数定义的最前面也加上了__declspec(dllimport))。
而且由于BCB和VC++成立函数名转换的做法不同。所以在VC中最好是输出函数为C函数的DLL,如果输出函数是C++类,则可能无法调用。
我的解决办法(经过本人实验证明的,共2种)
方法1:VC编译c文件生成dll时导出函数头文件加上extern "C"{}关键字,函数声明和定义处再加调用约定描述符__cdecl,然后将函数声明和定义处都加上一个下划线就没有问题了。
EXAMPLE:
假设我VC的dll中包含int myFunction(void),.c文件中函数实现处的正确写法是:
__declspec(dllexport) int __cdecl _myFunction(void)
{
        // add your code here
}
.h文件中函数声明处的正确写法如下
__declspec(dllexport) int __cdecl _myFunction(void);
BCB调用时只要包含lib文件,具体操作步骤:
运行implib bcb.lib vc.dll
project->add to...下拉框中选择.lib类型,打开刚才通过implib和vc的dll生成的lib文件
在工程中用到dll的.c源文件中包含该dll的头文件
调用时直接写 int i = myFunction(); 即可。

方法2:仅对VC编译C文件生成dll时有效,导出函数头文件加上extern "C"{}关键字。BCB的Project->option->advanced compiler下的Calling convention中选择Stdcall就可以直接调用VC的.c文件编译生成的动态链接库了。

VC调用c++builder的dll: (参考:MSDN2000)
VC中无LIB时的DLL隐式链接,制作与VC++相符合的LIB函数符号输入库(转)请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
1.使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
EXAMPLE:
DUMPBIN VideoDeCoder.dll /EXPORTS /OUT:VideoDeCoder.def
2.将导出的.DEF文件整理为一符合.DEF个数的函数导出文件(整理过程巨乱巨复杂,懒得举例了,后面有简便方法^_^)
3.使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
EXAMPLE:
LIB/DEF:VideoDeCoder.def /MACHINE:IX86
4.连接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
error LNK2002:unresolved external symbol "functionname@nn"
提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立LIB,重新链接即可.
这样就制作成功了符合VC调用方式的LIB了!

要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,这种方法只能应用于输出为C格式的__stdcall调用方式,只要做一点点修改就可以成为符合VC的DEF文件!
IMPDEF xxx.def xxx.dll
只要将BCB的DEF文件中函数申明格式转换为vc识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
vc调用bcb的我没试过,不过可以参照上面的格式自己改改好了:)


 

相关文章推荐

c++builder调用vc的dll

 联系订阅随笔- 93  文章- 0  评论- 3  c++builder调用vc的dll $bcb/bin目录中有个implib.exe 把你...

c++builder ZIP文件解压与压缩(ZLIB DLL调用),目录复制与删除整合的自用类,可自行扩张!

头文件:ZipAndFile.h //--------------------------------------------------------------------------- #if...

C++Builder建立及调用DLL

  • 2015-01-28 09:36
  • 42KB
  • 下载

BCB(C++Builder或Embarcadero XE)中调用托管DLL的方法(C++调用C#的DLL)

有时候我们的C++代码需要调用C#写的DLL,这就带来一个问题,非托管程序如何调用托管DLL?解决方法是:把C#写的DLL注册成COM组件,这样就可以非托管程序中调用了。详细操作步骤请见本图文教程。

C++Builder将对话框封装进Dll

一、 首先要新建dll工程   我使用的是C++builder 2010。设置如图,具体原因并没有时间深究。 二、在项目中增加一个对话框 平时我们在 VCL Forms Application中添加窗...

c++builder调用VC的dll以及VC调用c++builder的dll

解析__cdecl,__fastcall, __stdcall 的不同: 在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。 比如说__cdecl,它是标准的c方法的堆栈调用...

opencv 在VC、MinGW-GCC、及C++Builder中的运用

要使用OpenCV,需要经过以下几步: 1、下载OpenCV1.0:     http://www.intel.com/technology/computing/opencv/index.htm ...

C++builder(Xe5)下加载VC动态库的两种方法

这里分为两种方式:动态加载的

C++ builder 调用VC 封装的dll组件

C++builder调用自己写的组件或者VC写的dll,还是很方便的,但是过程中会有很多细节问题,            我很负责人的想骂网上那些不不负责任,写出方法,直接粘贴别人方法的,不整理的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)