如何在Delphi6中调用VC++写的DLL中的重载函数?(100分)

  • 主题发起人 主题发起人 Jhao
  • 开始时间 开始时间
J

Jhao

Unregistered / Unconfirmed
GUEST, unregistred user!
能否给个例子? 谢谢!
另外能否说明调用VC++的DLL时,用stdcall还是cdecl?
 
看来没人理,我再做说明:
VC++的DLL中定义了一个重载函数,如
int someFun(char var);
int someFun(int var);
如果在Delphi中引入这个函数会出现"找不到入口"的错误,Delphi应该有解决这种问题的机制,请问哪位高手知道.谢谢!
 
当C++使用了_stdcall输出时,Visual C++编译器修改了函数名,在前面加了个下划线,
在后面加了个@符号和传给该函数的参数的字节数,如果用VC来调用没有任何问题,但用
其他工具问题就来了,因为你根本找不到这个名字的函数,因为它变成了 _funcname@8(此处为参数字节数)
而你用的是funcname去找,因此会“找不到入口”,解决的办法是:
在DLL的源代码模块中,加入下面一行
#pragma comment(linker,"/export:funcname=_funcname@8")
funcname为你的函数名
8为你的参数的字节数和,(如果有多个参数为多个参数的字节总和)
例如你的程序应该写 someFun(int var)--》#pragma comment(linker,"/export:someFun=_someFun@4")
someFun(char var)--》#pragma comment(linker,"/export:someFun=_someFun@1")
另外,用stdcall 还是cdecl主要是根据DLL函数中引出类型来定的,一定要相符,因为它告诉
系统由谁来清除参数堆栈
 
谢谢, 不过问题关键在于这是一个重载的函数,我还要在Delphi中重新定义所有的重载函数吗?
如果DLL只输出一个函数名,如someFun,那么我该怎么做呢?
 
听说有一本<<Delphi 5.0 程序设计--高级编程>>的书中专门讨论这个问题,谁有这本书,请帮我查一下,谢谢!
 
调用VC++的DLL时,也是用stdcall,在使用DLL中重载函数时,Delphi
只允许调出一个重载函数,它需要在调用子句中区分不同名称,如:
exporte
someFun(char var),
someFun(int var) name 'IsomeFun';
关于重载,Delphi的OpenGL.pas单元中有一系列范例,你可以看一看!
看个例了吧:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)
int WINAPIdo
uble (int n)
{
return n * 2;
}
extern "C" __declspec(dllexport)
int WINAPI Triple (int n)
{
return n * 3;
}
__declspec(dllexport)
int WINAPI Add (int a, int b)
{
return (a + b);
}

//以下是在Dlphi中调用示例
unit CallCppF;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Spin, ExtCtrls;
type
TForm1 = class(TForm)
BtnDouble: TButton;
SpinEdit1: TSpinEdit;
Label1: TLabel;
BtnTriple: TButton;
Label2: TLabel;
SpinEdit2: TSpinEdit;
BtnAdd: TButton;
Label3: TLabel;
Edit1: TEdit;
Bevel1: TBevel;
procedure BtnDoubleClick(Sender: TObject);
procedure BtnTripleClick(Sender: TObject);
procedure BtnAddClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
//定义DLL函数
function Add (A, B: Integer): Integer;
stdcall;
external 'CPPDLL.DLL' name '@Add$qqsii';
functiondo
uble (N: Integer): Integer;
stdcall;
external 'CPPDLL.DLL' name 'Double';
function Triple (N: Integer): Integer;
stdcall;
external 'CPPDLL.DLL';
procedure TForm1.BtnDoubleClick(Sender: TObject);
begin
SpinEdit1.Value :=do
uble (SpinEdit1.Value);
end;

procedure TForm1.BtnTripleClick(Sender: TObject);
begin
SpinEdit2.Value := Triple (SpinEdit2.Value);
end;

procedure TForm1.BtnAddClick(Sender: TObject);
begin
Edit1.Text := IntToStr (Add (
SpinEdit1.Value, SpinEdit2.Value));
end;

end.

 
重载其实就是通过参数区分的
 
感谢dodo的回答! 不过我的问题好象还是没有解决.OpenGl.pas我看了一下, 与我的问题有一个不相同的地方,就是OpenGl.pas中重载是Delphi本身函数的重载,如:
procedure glColor(red, green, blue: GLbyte);
external opengl32 name 'glColor3b';
procedure glColor(red, green, blue: GLdouble);
external opengl32 name 'glColor3d';
也就是说在DLL文件中这是两个函数. 而我主要想知道在DLL文件中如果存在重载的函数,例如上面的例子,如果glColor是在DLL中已经重载的,那么我在Delphi中如何使用这个函数?
能详细说明一下如何实现吗?
谢谢!
 
后退
顶部