为什么BCB 调Dll这么麻烦,请大家帮忙看看啊!

yusmt 2010-04-13 12:31:44
别人写的DLL,有头文件,有VC的lib文件,就是没有办法正确调用。
我首先使用静态调用,方法如下.
1.将LIB文件 add to project
2.#include "MyDll.h";
后编译出错,提示 contains invalid OMF record, type 0x21 (possibly COFF)
然后我上网查,说要使用implib MyDll.lib MyDll.dll 导出的LIB

之后我使用implib导出了LIB并放在当前路径下
编译又报错
[Linker Error] Unresolved external 'ShowForm()' referenced from c:\a\UNIT1.OBJ
有点晕了

然后我使用动态调用,但因为这个dll的函数要在许多的窗体调用,所以我想将其定义在一个单元中。代码如下
//头文件Unit2.h里
//---------------------------------------------------------------------------
[code=C/C++]
#ifndef Unit2H
#define Unit2H
#include <StdCtrls.hpp>

char * _stdcall (*ShowForm)(char *);
double (*Add)(double x ,double y);
void loadDll();
HINSTANCE hInst=NULL;


//---------------------------------------------------------------------------
#endif
//源文件Unit2.h里
#pragma hdrstop

#include "Unit2.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)

void loadDll()
{
hInst = LoadLibrary("MyDll.DLL");
if(hInst)
{
(FARPROC &)ShowForm=GetProcAddress(hInst,"ShowForm" );
(FARPROC &)Add=GetProcAddress(hInst,"Add" );

}
else
{
// MessageBox(Handle,"无法加载DllServer.dll文件","信息提示",MB_OK);
FreeLibrary(hInst);
}
}

之后在窗体中调用,但是会出错
void __fastcall TForm1::FormCreate(TObject *Sender)
{
loadDll();
ShowForm(Edit1->Text.c_str());
}[/code]

但是将源文件中的代码放在窗体Unit1单元中执行一次就没有问题,可以正常使用,这是什么原因?(虽然在窗体1中可以正常使用,但在窗体2中还是不能正常调用)
我彻底晕了!
...全文
239 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zou1881 2010-04-17
  • 打赏
  • 举报
回复
我也有问题没解决,还是基本功不行。
周药师 2010-04-16
  • 打赏
  • 举报
回复
xjq2003 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 keiy 的回复:]
1.VC的lib与BCB格式不同,不能直接调用,用implib是可以的,但可能要加-a参数
2.动态调用时
1)你最好判一下GetProcAddress返回值,如果函数找不到,会出错的
2)你的程序有问题:
void loadDll()
{
hInst = LoadLibrary("MyDll.DLL"); //第二次又重新加载
if(hInst)
{
(FAR……
[/Quote]kan
Waiting4you 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yusmt 的回复:]

谢谢你的回复,静态调用成功,原来是要修改VC版的头文件,也就是你所说的3)。

根据BCB编写DLL终极手册上的写法,使用imdef 生成Ref文件,然后做相应的修改

但运态调用作了以上修改后依然失败,还是同开始一样,当void loadDll()写在窗体代码中时,可以正常调用,但是写在非窗体中则调用失败,调用DLL中的函数没有指向正确的位置.
而且在一个窗体中运行过Void loa……
[/Quote]
从你说的情况看应该已经取得了DLL中的函数。
请确认一下调用约定是否一致,比如VC的DLL里用了__stdcall,而在BCB里没加这类事情。
至于静态调用,VC的DLL有加和不加下划线的情况,如果implib不行,加个-a试试吧。
我的一个项目里就是用VC写了一个WTL的窗体,把它嵌在BCB的模态窗体里,运行正常,唯一的问题是TAB键跳转不过去,一直没解决。
zhanghelpsgz 2010-04-13
  • 打赏
  • 举报
回复
LIB要用DLL在BCB里面重新编译
sundl2268 2010-04-13
  • 打赏
  • 举报
回复
看来很复杂,呵呵,进来学习了
yusmt 2010-04-13
  • 打赏
  • 举报
回复
谢谢你的回复,静态调用成功,原来是要修改VC版的头文件,也就是你所说的3)。

根据BCB编写DLL终极手册上的写法,使用imdef 生成Ref文件,然后做相应的修改

但运态调用作了以上修改后依然失败,还是同开始一样,当void loadDll()写在窗体代码中时,可以正常调用,但是写在非窗体中则调用失败,调用DLL中的函数没有指向正确的位置.
而且在一个窗体中运行过Void loaddll()并且在此窗体中可以正常调用后,在另一个窗体中调用依然会失败,需要在另一个窗体中再次写上Void loaddll()的代码并调用。
也就是说Void loaddll()中的代码还能写成全局的函数?不知为何
柯本 2010-04-13
  • 打赏
  • 举报
回复
1.VC的lib与BCB格式不同,不能直接调用,用implib是可以的,但可能要加-a参数
2.动态调用时
1)你最好判一下GetProcAddress返回值,如果函数找不到,会出错的
2)你的程序有问题:
void loadDll()
{
hInst = LoadLibrary("MyDll.DLL"); //第二次又重新加载
if(hInst)
{
(FARPROC &)ShowForm=GetProcAddress(hInst,"ShowForm" );
(FARPROC &)Add=GetProcAddress(hInst,"Add" );

}
else //这个else也有问题
{
// MessageBox(Handle,"无法加载DllServer.dll文件","信息提示",MB_OK);
FreeLibrary(hInst); //这个很有问题,这里hInst=NULL,当然错
}
}
改一下:
void loadDll()
{
if(hInst==NULL)
{
hInst = LoadLibrary("MyDll.DLL");
if ( hInst)
{
(FARPROC &)ShowForm=GetProcAddress(hInst,"ShowForm" );
if (ShowForm==NULL)
::MessageBox(NULL,"无法找到ShowForm函数","信息提示",MB_OK);
(FARPROC &)Add=GetProcAddress(hInst,"Add" );
if (Add==NULL)
::MessageBox(NULL,"无法找到Add函数","信息提示",MB_OK);
}
else
::MessageBox(NULL,"无法加载DllServer.dll文件","信息提示",MB_OK);
}
3)注意函数的定义(要与VC相同)特别是调用方式(_stdcall,_cdecl)
yusmt 2010-04-13
  • 打赏
  • 举报
回复
怎么没有人回复啊!
难道dll的定义一定要在窗体中进行吗?

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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