VC调用BCB的DLL中的类函数遇到的问题

puddingli 2015-07-15 07:22:43
有一个别人用BCB做的dll(TDIcom.dll),我想通过VC来调用它。(用的是VS2010)
以前其他BCB的dll中的非类函数都能解决,但是这次碰到个dll里面有个类LibTDI,调用时候一直出错,该怎么解决?谢谢。
错误如下:
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall LibTDI::LibTDI(void)" (__imp_??0LibTDI@@QAE@XZ),该符号在函数 "public: __thiscall CxrayworkerDlg::CxrayworkerDlg(class CWnd *)" (??0CxrayworkerDlg@@QAE@PAVCWnd@@@Z) 中被引用
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: int __thiscall LibTDI::Set_TDI_V2(int,int,int)" (__imp_?Set_TDI_V2@LibTDI@@QAEHHHH@Z),该符号在函数 __catch$?OnInitDialog@CxrayworkerDlg@@MAEHXZ$0 中被引用
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: int __thiscall LibTDI::TDI_SwitchGear(int)" (__imp_?TDI_SwitchGear@LibTDI@@QAEHH@Z),该符号在函数 __catch$?OnInitDialog@CxrayworkerDlg@@MAEHXZ$0 中被引用
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: int __thiscall LibTDI::CheckConnection(void)" (__imp_?CheckConnection@LibTDI@@QAEHXZ),该符号在函数 __catch$?OnInitDialog@CxrayworkerDlg@@MAEHXZ$0 中被引用
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: bool __thiscall LibTDI::Connect(void)" (__imp_?Connect@LibTDI@@QAE_NXZ),该符号在函数 __catch$?OnInitDialog@CxrayworkerDlg@@MAEHXZ$0 中被引用
1>xrayworkerDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __thiscall LibTDI::Disconnect(void)" (__imp_?Disconnect@LibTDI@@QAEXXZ),该符号在函数 "public: void __thiscall CxrayworkerDlg::OnBnClickedCancel(void)" (?OnBnClickedCancel@CxrayworkerDlg@@QAEXXZ) 中被引用
1>D:\Projects\xrayworker\Debug\xrayworker.exe : fatal error LNK1120: 6 个无法解析的外部命令


通过BCB的IMPDEF工具生成的TDIcom.def,内容:

LIBRARY TDICOM.DLL

EXPORTS
@LibTDI@BinToInt$q3USC @2 ; LibTDI::BinToInt(USC)
@LibTDI@CheckConnection$qv @6 ; LibTDI::CheckConnection()
@LibTDI@Connect$qv @1 ; LibTDI::Connect()
@LibTDI@Disconnect$qv @5 ; LibTDI::Disconnect()
@LibTDI@Get_TDI_V2$qii @8 ; LibTDI::Get_TDI_V2(int, int)
@LibTDI@IntToBin$qus @3 ; LibTDI::IntToBin(unsigned short)
@LibTDI@OnWait$qv @7 ; LibTDI::OnWait()
@LibTDI@Set_TDI_V2$qiii @9 ; LibTDI::Set_TDI_V2(int, int, int)
@LibTDI@TDI_SwitchGear$qi @10 ; LibTDI::TDI_SwitchGear(int)
@LibTDI@checksum$qpucus @4 ; LibTDI::checksum(unsigned char *, unsigned short)
___CPPdebugHook @11 ; ___CPPdebugHook


头文件tdi.h,就是主程序调用里面的LibTDI类的函数出错的

//tdi.h

#ifndef TDI_H
#define TDI_H

#ifdef _CLASSINDLL
#define CLASSINDLL_CLASS_DECL __declspec(dllexport)
#else
#define CLASSINDLL_CLASS_DECL __declspec(dllimport)
#endif

#define TDI_VER 1
#define TDI_SPD 2
//#define TDI_LINES 3
//#define TDI_GAIN 4
#define TDI_GAIN_V2 3
//#define TDI_OFFSET 5
#define TDI_OFFSET_V2 4
//#define TDI_V2_GAIN_OFFSET 3
#define TDI_CMD_END 0x0D
#define TDI_CMD_END2 0x0A


#define ERR_TDI_232_DISCONNECT -1
#define ERR_TDI_232_NORESPOND -2
#define ERR_TDI_PCI_NOHANDLE -3
#define ERR_TDI_PCI_FUNCNOLOAD -4
#define ERR_TDI_CMD_OK 1
#define ERR_TDI_CMD_SYNTAXERR -5//s
#define ERR_TDI_CMD_UNKNOWN -6

#define TDI_SENSORNUM 20
#define TDI_SENSOR_PIXELNUM 143
#define TDI_AVAILABLE_SENSOR_PIXELNUM 138
#define TDI_AVAILABLE_SENSOR_PIXELNUM_OFFSET 2
#define TDI_UNCERTAIN_LINES 20

#define TDI_STAR 1
#define TDI_STOP 2
#define TDI_HVOLTAGE_ON 3
#define TDI_HVOLTAGE_OFF 4

#define TDI_INTEGRAL_FACTOR 0.75/270.0


#define TDI_PIXEL_MEASURE 15.0
#define TDI_LINE_INTEGRAL_TIME(value) TDI_INTEGRAL_FACTOR*value
#define TDI_LINE_TRANS_TIME(value) TDI_INTEGRAL_FACTOR*1000+(value-270)*TDI_INTEGRAL_FACTOR
class USC{
public:
BYTE high ;
BYTE low ;
USC(){high=0;low=0;}
USC(BYTE h,BYTE l)
{
high=h;
low=l;
}
} ;

#pragma comment(lib,"TDIcom.lib")
class CLASSINDLL_CLASS_DECL LibTDI {

void OnWait();
BYTE checksum(BYTE *list,WORD len);
WORD BinToInt(USC c) ;
USC IntToBin(WORD c) ;

public:
LibTDI(){};
bool Connect();
void Disconnect();
BOOL CheckConnection();

int Get_TDI_V2(int code,int para);
BOOL Set_TDI_V2(int code,int para,int para2);
BOOL TDI_SwitchGear(int type) ;
};
#endif

...全文
314 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
puddingli 2015-07-31
  • 打赏
  • 举报
回复
引用 18 楼 u010030181 的回复:
[quote=引用 17 楼 mjdy123 的回复:] [quote=引用 16 楼 u010030181 的回复:] 出现这个有很多的原因的,你那个dll是运行在32?还是64?位操作系统下,如果你的DLL是64位的,在win32下调用也会出现那个错误...
运行在64位操作系统下,dll应该是32位的[/quote] http://www.pediy.com/kssd/pediy06/pediy6181.htm http://www.codeguru.com/cpp/w-p/dll/importexportissues/article.php/c123/Explicitly-Linking-to-Classes-in-DLLs.htm 最近我也想直接用VC调用BCB的DLL(包含类的),后来发现是函数名扩展的问题,因为两个平台对C++的函数名进行扩展不一样,就算你直接修改def文件生成了可供VC调用的lib,也没有用的……因为你lib可能生成对了,但是调用dll时又不是原来的的那个函数名了……上面两个连接或许有用,但我没实验,不过就算有用,也可能会出现莫名其妙的错误,《window核心编程》中提到:只有当导出C++类的模块使用的编译器与导入C++类的模块的开发人员与DLL模块的开发人员使用的是相同的工具包,否则我们应该避免从DLL中导出C++类,而且现实的情况也确实如此。[/quote] 谢谢,我先试试写一个新的dll,包裹在原来的DLL外面,看看这种方法行不行
QIUSQJF 2015-07-30
  • 打赏
  • 举报
回复
引用 17 楼 mjdy123 的回复:
[quote=引用 16 楼 u010030181 的回复:] 出现这个有很多的原因的,你那个dll是运行在32?还是64?位操作系统下,如果你的DLL是64位的,在win32下调用也会出现那个错误...
运行在64位操作系统下,dll应该是32位的[/quote] http://www.pediy.com/kssd/pediy06/pediy6181.htm http://www.codeguru.com/cpp/w-p/dll/importexportissues/article.php/c123/Explicitly-Linking-to-Classes-in-DLLs.htm 最近我也想直接用VC调用BCB的DLL(包含类的),后来发现是函数名扩展的问题,因为两个平台对C++的函数名进行扩展不一样,就算你直接修改def文件生成了可供VC调用的lib,也没有用的……因为你lib可能生成对了,但是调用dll时又不是原来的的那个函数名了……上面两个连接或许有用,但我没实验,不过就算有用,也可能会出现莫名其妙的错误,《window核心编程》中提到:只有当导出C++类的模块使用的编译器与导入C++类的模块的开发人员与DLL模块的开发人员使用的是相同的工具包,否则我们应该避免从DLL中导出C++类,而且现实的情况也确实如此。
puddingli 2015-07-29
  • 打赏
  • 举报
回复
引用 16 楼 u010030181 的回复:
出现这个有很多的原因的,你那个dll是运行在32?还是64?位操作系统下,如果你的DLL是64位的,在win32下调用也会出现那个错误...
运行在64位操作系统下,dll应该是32位的
QIUSQJF 2015-07-27
  • 打赏
  • 举报
回复
出现这个有很多的原因的,你那个dll是运行在32?还是64?位操作系统下,如果你的DLL是64位的,在win32下调用也会出现那个错误...
puddingli 2015-07-23
  • 打赏
  • 举报
回复
求助各位大牛啊~一直没能解决~
赵4老师 2015-07-18
  • 打赏
  • 举报
回复
将错误信息中出现的标识符放在百度里面搜一下,看其在哪个.lib中,然后在本地硬盘上搜索该.lib,如果没有,在网上搜索相关库或模块下载安装,然后将其所在目录填写到“附加依赖库所在目录”中,将其名字添加到“附加依赖库”中,重新连接。 VC6: 工程、设置、C/C++、分类:Preprocessor、附加包含路径:填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类:Input、附加库路径:填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类:Input、对象/库模块:填写附加依赖库的名字.lib 空格间隔多项 VS20xx: 项目、属性、C/C++、附加包含目录:填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录:填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项:填写附加依赖库的名字.lib 空格或分号间隔多项
worldy 2015-07-18
  • 打赏
  • 举报
回复
#pragma comment(lib,"TDIcom.lib")//必须确认TDIcom.lib文件存在
puddingli 2015-07-18
  • 打赏
  • 举报
回复
不行~我按上面10L,11L,12L的方法都试了~还是一样的错误~绝对路径也不行~lib文件确认存在~属性里面也加上了~还是一样~ 我百度了一下~是不是我前面用BCB的IMPDEF从TDIcom.dll导出的def要修改一下格式?然后再用修改好的def生成lib。那这个def该怎么改才能让VC来用?
puddingli 2015-07-18
  • 打赏
  • 举报
回复
引用 10 楼 yaozhiyong110 的回复:
[quote=引用 7 楼 mjdy123 的回复:] [quote=引用 6 楼 yaozhiyong110 的回复:] 你这个是没链接上 lib的问题...
我在头文件tdi.h里加入了#pragma comment(lib,"TDIcom.lib") 还是出错。 还有其他要加的地方吗?[/quote] 那有可能是你TDIcom.lib放置的位置不对 你先用绝对路径试试...[/quote] 不行~我按上面10L,11L,12L的方法都试了~还是一样的错误~绝对路径也不行~lib文件确认存在~属性里面也加上了~还是一样~ 我百度了一下~是不是我前面用BCB的IMPDEF从TDIcom.dll导出的def要修改一下格式?然后再用修改好的def生成lib。那这个def该怎么改才能让VC来用?
yaozhiyong110 2015-07-17
  • 打赏
  • 举报
回复
引用 7 楼 mjdy123 的回复:
[quote=引用 6 楼 yaozhiyong110 的回复:] 你这个是没链接上 lib的问题...
我在头文件tdi.h里加入了#pragma comment(lib,"TDIcom.lib") 还是出错。 还有其他要加的地方吗?[/quote] 那有可能是你TDIcom.lib放置的位置不对 你先用绝对路径试试...
puddingli 2015-07-17
  • 打赏
  • 举报
回复
引用 8 楼 redui 的回复:
你确定你包含它的头文件时没有定义_CLASSINDLL宏?必须不能定义这个宏,否则系统认为是你在导出类,因此到处找符号的实现,结果找不到。 如果不确定,在#include "tdi.h"之前加上 #undef _CLASSINDLL试试
没有定义,我直接把class CLASSINDLL_CLASS_DECL LibTDI换成class __declspec(dllimport) LibTDI也不行
redui 2015-07-17
  • 打赏
  • 举报
回复
你确定你包含它的头文件时没有定义_CLASSINDLL宏?必须不能定义这个宏,否则系统认为是你在导出类,因此到处找符号的实现,结果找不到。 如果不确定,在#include "tdi.h"之前加上 #undef _CLASSINDLL试试
puddingli 2015-07-17
  • 打赏
  • 举报
回复
引用 6 楼 yaozhiyong110 的回复:
你这个是没链接上 lib的问题...
我在头文件tdi.h里加入了#pragma comment(lib,"TDIcom.lib") 还是出错。 还有其他要加的地方吗?
yaozhiyong110 2015-07-17
  • 打赏
  • 举报
回复
你这个是没链接上 lib的问题...
puddingli 2015-07-17
  • 打赏
  • 举报
回复
@要追问请引用回复 @yaozhiyong110 @oyljerry 求助各位大牛,谢谢。 这个dll我不确定是否是BCB做的,不过应该没有包含BCB特有的函数,只不过头文件原来是用在BCB里面的。主要是碰到这个类,不知道该怎样调用。
puddingli 2015-07-16
  • 打赏
  • 举报
回复
引用 2 楼 fhw_bin_dl 的回复:
可能是BCB生成的lib格式较旧,VS2010无法识别。
我通过VC++的LIB工具用TDIcom.def新生成了一个lib
fhw217 2015-07-15
  • 打赏
  • 举报
回复
BCB对类函数的修饰方法与VC不一样。
fhw217 2015-07-15
  • 打赏
  • 举报
回复
可能是BCB生成的lib格式较旧,VS2010无法识别。
puddingli 2015-07-15
  • 打赏
  • 举报
回复
我在主程序里需要用LibTDI类定义一个成员变量 LibTDI tdi; 然后在各个成员函数里调用tdi里的函数
library fundll; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses ShareMem, // ShareMem 一定放第一个 Windows, Messages, SysUtils, math, strutils, registry , StdCtrls, ExtCtrls, ADODB, DB,dateutils,Dialogs; // fucs in 'fucs.pas'; const INPASSSTR='89ABCDEFGcdefghijkHIJ%^KLMN0123opqrstuOP -_\|/?@#$&*' ; //切记:Library 的名字大小写没关系,可是DLL-Func的大小写就有关系了。 // 在 DLL-Func-Name写成MyMax与myMAX是不同的。如果写错了,立即的结果是你调用到此DLL的AP根本开不起来。 //参数的大小写就没关系了。甚至不必同名。如原型是 (X,Y:integer)但引用时写成(A,B:integer),那是没关系的。 //切记:要再加个stdcall。书上讲,如果你是用Delphi写DLL,且希望不仅给 Delphi-AP也希望BCB/VC-AP等使用的话,那你最好加个Stdcall ; //参数型态:Delphi有很多种它自己的变量型态,这些当然不是DLL所喜欢的,Windows/DLL的母语应该是C。所以如果要传进传出DLL的参数,我们尽可能照规矩来用。这两者写起来,后者会麻烦不少。如果你对C不熟的话,那也没关系。我们以后再讲。 //3.将这些可共享的Func送出DLL,让外界﹝就是你的Delphi-AP啦﹞使用: //光如此,你的AP还不能用到这些,你还要加个Exports才行。 代码: //=============比较大小的函数=============== Function MyMax ( X , Y : integer ) : integer ; stdcall ; //stdcall 可以让 BCB/VC-AP等使用的 begin if X > Y then Result := X else Result := Y ; end ; //==============加密======================= function Inpass(s:string):string; stdcall ; var i:integer; passstr,dd:string; begin for i:=1 to length(s) do begin dd:=inttohex(ansipos(s[i],inpassstr),4); if dd='0000' then begin result:='0';exit end; passstr:=passstr+dd ; end; Result :=passstr; end; //==============解密======================= function Outpass(s:string):string;stdcall ; var pass,dd:string; i,leng:integer; begin leng:= floor(length(s)/4); pass:=''; for i:=1 to leng do begin dd:=ansimidstr(s,(i-1)*4+1,4); if strtoint('$'+dd)=0 then begin result:='0';exit;end; if strtoint('$'+dd)>78 then begin result:='0'; exit end; pass:=pass+ansimidstr(inpassstr,strtoint('$'+dd),1) ; end; Result :=pass ; end; //==========test========================= function jsjyh(strym:string):string;stdcall; var newstr1,he,oldstr:string; tj:boolean; i:integer; begin i:=1; he:=''; tj:=true; // 取出要参与校验和计算的字符串给oldstr if (length(strym) mod 2)0 then begin showmessage('你输入的源码个数有错,不能是奇数个,请重输入!'); exit; end; oldstr:=trim(strym); while tj=true do begin newstr1:=copy(oldstr,i,2); oldstr:=copy(oldstr,i+2,length(oldstr)-2); //开始计算校验和并给he变量 if he='' then begin he:=inttohex(strtointdef('$'+newstr1,16)+ strtointdef('$'+'00',16),2); he:=rightstr(he,2); end else begin he:=inttohex(strtointdef('$'+newstr1,16)+ strtointdef('$'+he,16),2); he:=rightstr(he,2); end; if length(oldstr) =0 then tj:=false; end; result:=strym+he; end; //============================================== {$R *.RES} //将这些可共享的Func送出DLL,让外界﹝就是你的Delphi-AP啦﹞使用: //光如此,你的AP还不能用到这些,你还要加个Exports才行。 代码: exports MyMax,Inpass,Outpass,jsjyh; begin end.
一款用于共享软件加密的动态链接库文件,包含了获取硬盘物理序列号及BlowFish、MD5、SHA512、RIPEMD160、Secret16、MD5FileCheck、CRCFileCheck等多种强大加密算法,可以非常方便的用于软件的各加密需求。支持VC/VB/BCB/Delphi等各Windows平台下的开发工具,软件同时提供详细的函数定义说明、示例及各开发工具使用的源代码。 软件功能: (1)可用于获取硬盘序列号(IDE/SCSI),支持Win9x/Me/NT/2000/XP。 (2)内置BlowFish、MD5、SHA512、RIPEMD160、Secret16、MD5FileCheck、 CRCFileCheck等多种强大加密算法来对软件进行加密保护。 (3)支持Window平台下的各开发工具,如VC/VB/BCB/Delphi/PB/VFP等。 (4)可以非常方便的同时使用多种加密算法来对软件进行加密保护。 打包文件说明: Reg.dll-------------------加密算法动态链接库文件。 Reg.h---------------------在 VC(C/C++) 和 BCB 开发环境下的头文件。 Reg.lib-------------------在 VC(MFC) 开发环境下的 Library 文件。 Reg.bas-------------------在 VB 开发环境下的 Module 文件。 Readme.txt----------------纯文本格式说明文件。 Help.chm------------------函数接口详细定义说明文件。 MFC_TestEncryDll.zip------MFC调用Reg.dll进行加密示例。 VB6_TestEncryDll.zip------VB6调用Reg.dll进行加密示例。 CB5_TestEncryDll.zip------BCB5调用Reg.dll进行加密示例。 Delphi_TestEncryDll.zip---Delphi调用Reg.dll进行加密示例。 函数详细说明请参见Help.chm具体函数说明部分及相关示例代码。

1,221

社区成员

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

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