BCB如何调用VC带类的dll?

过客猫2022 2006-07-10 03:17:07
LoadLibary
implib
coff2lib我都试过了
下面是dll头文件:
#ifdef TTTTTTT_EXPORTS
#define TTTTTTT_API __declspec(dllexport)
#else
#define TTTTTTT_API __declspec(dllimport)
#endif

// This class is exported from the ttttttt.dll
class TTTTTTT_API CTtttttt {
public:
CTtttttt(void);
// TODO: add your methods here.
int GetAAA();
void SetAAA(int v);
private:
int aaa;
};

extern TTTTTTT_API int nTtttttt;

TTTTTTT_API int fnTtttttt(void);
//下面是dll实现!

#include "stdafx.h"
#include "ttttttt.h"

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


// This is an example of an exported variable
TTTTTTT_API int nTtttttt=0;

// This is an example of an exported function.
TTTTTTT_API int fnTtttttt(void)
{
return 42;
}

// This is the constructor of a class that has been exported.
// see ttttttt.h for the class definition
CTtttttt::CTtttttt()
{
return;
}

int CTtttttt::GetAAA()
{
return aaa;
}
void CTtttttt::SetAAA(int v)
{
aaa = v;
}
...全文
617 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenjun716 2006-07-26
  • 打赏
  • 举报
回复
这种贴太多了!
jaffy 2006-07-17
  • 打赏
  • 举报
回复
keiy() 的方法很好,先MARK
柯本 2006-07-16
  • 打赏
  • 举报
回复
经过多次实验,终于成功调用
首先,列举VC与BCB在生成代码时的区别
1.__declspec(dllexport)/__declspec(dllimport)
VC生成__stdcall前缀,而BCB生成__cdecl
2.类.
VC的类成员函数(我用VC2003)生成的居然是__fastcall(register调用),即使用/Gd编译选项,也无法改变它的调用方式,而BCB即使定义为__fastcall,也无法与VC的兼容(因为两个编译器用不同的寄存器),另外,BCB的类成员与它的类定义有关, 如,类定义为__cdecl,那它所有的成员函数都为__cdecl
基于上面分析,如果不改VC源码,BCB还是无法调用它(除非对栈进行特殊处理,理论上可以,太繁,我不作测试了)
我是这样修改(VC中):
#ifdef TTTTTTT_EXPORTS
#define TTTTTTT_API __declspec(dllexport)
#else
#define TTTTTTT_API __declspec(dllimport)
#endif

// This class is exported from the ttttttt.dll
class TTTTTTT_API CTtttttt {
public:
CTtttttt(void);
// TODO: add your methods here.
int _cdecl GetAAA(); //这时,定义为_cdecl,以下同
void _cdecl SetAAA(int v);
private:
int aaa;
};

extern TTTTTTT_API int nTtttttt;

TTTTTTT_API int fnTtttttt(void);
将VC生成dll后,BCB的处理为
1.写一个def文件(我的为vcdll.def)
LIBRARY VCDLL.DLL

EXPORTS

@CTtttttt@$bctr$qqsv @2 ; CTtttttt::CTtttttt()
@CTtttttt@GetAAA$qv @3 ; CTtttttt::GetAAA()
@CTtttttt@SetAAA$qi @4 ; CTtttttt::SetAAA(int)
@fnTtttttt$qv @5 ; fnTtttttt()
_nTtttttt @6 ; _nTtttttt

2.用implib vcdll vcdll.def生成vcdll.lib并加入BCB的项目
3.将头文件作以下修改
#ifdef TTTTTTT_EXPORTS
#define TTTTTTT_API __declspec(dllexport)
#else
#define TTTTTTT_API __declspec(dllimport)
#endif

// This class is exported from the ttttttt.dll
class __stdcall TTTTTTT_API CTtttttt { //这里,定义为__stdcall
public:
CTtttttt(void);
// TODO: add your methods here.
int __cdecl GetAAA();
void __cdecl SetAAA(int v);
private:
int aaa;
};

extern TTTTTTT_API int nTtttttt;

TTTTTTT_API int fnTtttttt(void);

4.测试程序:
//---------------------------------------------------------------------------

#include <vcl.h>
#include "ttttttt.h"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->Text=fnTtttttt();
Edit2->Text=nTtttttt;
CTtttttt mm;
mm.SetAAA(330);
Edit3->Text=mm.GetAAA();
}
//---------------------------------------------------------------------------
//经测试,完全成功

其实,这种调用意义并不大,不过,通过这些测试,可以让我们更好的了解VC/BCB的编译方式,我也只是给大家提供一个思路,欢迎大家拿出更好的方法
柯本 2006-07-16
  • 打赏
  • 举报
回复
的确,MFC和BCB在自成二进制时,对栈的调用不同,所以,即使你用implib的def别名使编译通过.也不能正确得到运行结果
以下是我的测试:(我的文件名为vcdll.cpp)
先编译vcdll.cpp生成vcdll.dll
然后写一vcdll.def文件
LIBRARY VCDLL.DLL
EXPORTS
@CTtttttt@$bctr$qv @2 ; CTtttttt::CTtttttt()
@CTtttttt@GetAAA$qv @3 ; CTtttttt::GetAAA()
@CTtttttt@SetAAA$qi @4 ; CTtttttt::SetAAA(int)
@fnTtttttt$qv @5 ; fnTtttttt()
_nTtttttt @6 ; _nTtttttt

(此文件是用bcb生成的dll分析后写成)
然后:
implib vcdll vcdll.def
得到vcdll.lib并将它加入bcb的项目

bcb的程序如下;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->Text=fnTtttttt(); //正确
Edit2->Text=nTtttttt; //正确
class CTtttttt mm; //调用构造函数成功
mm.SetAAA(120); //非法地址错
Edit3->Text=mm.GetAAA(); //非法地址错
}
===========================================================================
在DLL中,VC的类不能由BCB调用.但非类函数是没问题的
我以前回过关于此方面的,我的解决方案是,将vc的类的成员函数,重新封装成非类函数,供bcb调用
  • 打赏
  • 举报
回复
好像不大可能的事情,C++没有二进制标准,就算是微软自己的不同版本的编译器也不互相兼容。
jiangshx 2006-07-14
  • 打赏
  • 举报
回复
dll头文件有问题,这样试试


//#ifdef TTTTTTT_EXPORTS
#define TTTTTTT_API __declspec(dllexport)
//#else
//#define TTTTTTT_API __declspec(dllimport)
//#endif

// This class is exported from the ttttttt.dll
class TTTTTTT_API CTtttttt {
public:
CTtttttt(void);
// TODO: add your methods here.
int GetAAA();
void SetAAA(int v);
private:
int aaa;
};
extern "C" TTTTTTT_API int nTtttttt;
extern "C" TTTTTTT_API int fnTtttttt(void);
过客猫2022 2006-07-14
  • 打赏
  • 举报
回复
?
BlueDeepOcean 2006-07-11
  • 打赏
  • 举报
回复
http://www.qiqi.com/book/pc/c++/12/chap12.htm
daydayup234 2006-07-10
  • 打赏
  • 举报
回复
http://www.ccrun.com/article/go.asp?i=498&d=f36445

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧