有关DLL调用的问题
我使用vc++编写了一个DLL,在输出函数中我使用的动态调用另外一个DLL的代码,
例如
a 输出test
b 输出testb
在a的test中,动态调用b的testb函数,使用API函数hinst=Loadlibrary("b");
pTestb=(pTestb)GetProcAddress("testb");
在其他程序中调用a的test函数。
此方法在VB,VC,PB中都可以正常运行,但在delphi中却无法正常运行,跟踪得知,在a的GetProcAddress函数时返回空值。why???
请DELPHI高手指教。
问题点数:0、回复次数:7Top
1 楼aiirii(ari-http://spaces.msn.com/members/aiirii/)回复于 2003-11-01 15:30:35 得分 0
可能:
你的dll對應函數聲明不對;
注意你函數名的大小寫!
或者貼出你的代碼!!Top
2 楼Seahilly(小峰)回复于 2003-11-01 15:33:16 得分 0
Delphi调用VC++的DLL,做法如下:
1、在VC++的.cpp文件中说明输出函数的名字、类型、调用方式、定义函数执行体:
extern "C" __declspec(dllexport) void VCvoidfunction(......)
{
.......
return;
}
extern "C" __declspec(dllexport) DWORD VCdwordfunction(......)
{
.......
return ....;
}
2、在Delphi中说明,假定做一个单独的引入单元:
1)说明函数类型:
Type TVCvoidfunction=Function(......); Cdecl; //函数类型
Type TVCdwordfunction=Function(......); Cdecl; //函数类型
2)定义函数变量:
Var VCvoidfunction: TVCvoidfunction;
VCdwordfunction: TVCdwordfunction;
3、在Delphi程序中首先动态连接DLL:
DLL_Handle:=LoadLibrary(PChar(DLLPath));
DLL_Handle>0 Then //若加载成功,
Begin //则依次定位函数
Try
@VCvoidfunction :=GetProcAddress(DLL_Handle,'VCvoidfunction');
@VCdwordfunction:=GetProcAddress(DLL_Handle,'VCdwordfunction);
Except
FreeLibrary(DLL_Handle);
End
End
4、在Delphi程序中调用VC的DLL中函数:
直接使用函数名,按Delphi的要求使用。
注意,VC参数中的&对应Delphi的Var。
Top
3 楼Seahilly(小峰)回复于 2003-11-01 15:34:35 得分 0
但是要注意:
1、VC++的函数名是大小写敏感的,在Delphi引入时要注意;
2、调用方式,VC++自己缺省为C方式,对应Delphi的“Cdel”,最好都用StdCall;
3、参数对应关系,如*对应指针,&对应Var等。
4、如果VC++输出的是个类,则Delphi也能够调用,可以采用包装法,但是,最好采用虚拟表法。
Top
4 楼stlyy(砺刀)回复于 2003-11-01 15:39:11 得分 0
activex 输出方法:
STDMETHODIMP CTaxwareIC::IcReadFile(BSTR strPath, BSTR *strError)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
USES_CONVERSION;
TCHAR szCause[255]={0};
TCHAR szBuf[255];
int nRet=-1;
CString strTmp;
CComBSTR strRet;
GetFileFromCard process;
HINSTANCE hinst=NULL;
TRY{
///////////////////////断点可以跟踪到此处
AfxMessageBox("aaaaaa");
hinst= LoadLibrary("mwic.dll");
lstrcpy(szBuf,OLE2A(strPath));
if(hinst==NULL)
{
return -1;
}
process=(GetFileFromCard)GetProcAddress(hinst, "GetFileFromCard");
try{
nRet=process(szBuf,szCause);
}catch(...)
{
nRet=999;
strcpy(szCause,"未知系统错误");
}
AfxMessageBox("afdfasdf");
strTmp.Format("%03d%s",nRet,szCause);
strRet.Append(strTmp.GetBuffer(strTmp.GetLength()));
strTmp.ReleaseBuffer();
*strError=strRet.Detach();
strRet.Empty();
FreeLibrary(hinst);
}
CATCH_ALL(e)
{
if(hinst!=NULL)
FreeLibrary(hinst);
TCHAR szCause[255];
e->GetErrorMessage(szCause,255);
strTmp.Empty();
strTmp="002系统异常错误|";
strTmp+=szCause;
strTmp.Empty();
strRet.Append(strTmp.GetBuffer(strTmp.GetLength()));
strTmp.ReleaseBuffer();
*strError=strRet.Detach();
strRet.Empty();
}
END_CATCH_ALL
return S_OK;
}
=========================================
delphi 编写
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleServer, MyObject_TLB, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
obj: MyObject;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
str:String;
begin
str:=obj.IcReadFile('d:\tmp\ddd.bin');
ShowMessage(str);
end;
end.
我使用的时COM对象,换成dll错误一样,我可以在VC++的调试器上跟踪到执行位置Top
5 楼stlyy(砺刀)回复于 2003-11-01 15:41:39 得分 0
上面的代码可以被VB正常使用,
在delphi中,process=(GetFileFromCard)GetProcAddress(hinst, "GetFileFromCard");
此句返回NULL;Top
6 楼aiirii(ari-http://spaces.msn.com/members/aiirii/)回复于 2003-11-04 19:55:56 得分 0
>>process=(GetFileFromCard)GetProcAddress(hinst, "GetFileFromCard");
這句, 無論是VB,VC,delphi應該執行都一樣的啊!!! 如果是這樣的問題, 是不是路徑的問題??Top
7 楼saien(精益求精)回复于 2003-11-04 21:57:14 得分 0
upTop




