加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何从DLL导出重载函数?

发布时间:2020-12-15 09:43:58 所属栏目:大数据 来源:网络整理
导读:德尔福Xe. 在模块Windows.pas中,我看到一种方法: function InterlockedExchangeAdd(Addend: PLongint; Value: Longint): Longint stdcall; overload;{$EXTERNALSYM InterlockedExchangeAdd}function InterlockedExchangeAdd(var Addend: Longint; Value: Lo
德尔福Xe.

在模块Windows.pas中,我看到一种方法:

function InterlockedExchangeAdd(Addend: PLongint; Value: Longint): Longint stdcall; overload;
{$EXTERNALSYM InterlockedExchangeAdd}
function InterlockedExchangeAdd(var Addend: Longint; Value: Longint): Longint stdcall; overload;
{$EXTERNALSYM InterlockedExchangeAdd}
...
function InterlockedExchangeAdd(Addend: PLongint; Value: Longint): Longint; external kernel32 name 'InterlockedExchangeAdd';
function InterlockedExchangeAdd(var Addend: Longint; Value: Longint): Longint; external kernel32 name 'InterlockedExchangeAdd';

意味着,DLL可以导出具有相同名称的函数.

我试着重复一遍:

我创建了这个项目

Program TestMyDll;

{$APPTYPE CONSOLE}

uses SimpleShareMem,SysUtils;

Function MyFunc(const X:Integer):string; StdCall; External 'MyDll.dll' Name 'MyFunc'; Overload;
Function MyFunc(const X:Extended):string; StdCall; External 'MyDll.dll' Name 'MyFunc'; Overload;

begin
  try
  Writeln;
  Writeln('MyDll test');
  Writeln('Int: ' + MyFunc(10));
  Writeln('Real: ' + MyFunc(10.55));
  Readln;
  except on E: Exception do Writeln(E.ClassName,' : ',E.Message);end;
end.

它正常编译.我进一步创建DLL:

Library MyDll;

uses
  SimpleShareMem,DllUnit1 in 'DllUnit1.pas';

{$R *.res}

begin
//test
MyFunc(10);MyFunc(10.55);
end.

……和模块DllUnit1.pas

Unit DllUnit1; Interface

Function MyFunc(const X:Integer):string; Overload; StdCall;
Function MyFunc(const X: Extended):string; Overload; StdCall;

Exports
MyFunc; // COMPILE ERROR

Implementation

Uses SysUtils;

Function MyFunc(const X:Integer):string;
begin
result:=Inttostr(x);
end;

Function MyFunc(const X: Extended):string;
begin
result:=Floattostr(x);
end;

end.

但在编译时我收到一个错误:[DCC错误] DllUnit1.pas(7):E2273没有带有此参数列表的’MyFunc’的重载版本存在.

在Delphi帮助中,我看到:

"Delphi Language Reference"/"The exports clause"
...
When you export an overloaded function or procedure from a dynamically loadable library,you must specify its parameter list in the exports clause. For example,exports
 Divide(X,Y: Integer) name 'Divide_Ints',Divide(X,Y: Real) name 'Divide_Reals';

On Windows,do not include index specifiers in entries for overloaded routines.

问题:

>如何正确地在模块DllUnit1中导出这些函数,以及是否可以在Delphi(以一个名称导出)中一般地使用它来从我的项目TestMyDll接收与开头一样的调用(来自windows.pas的示例) ?
>如果可以使用一个名称导出此类函数,那么通过从其他语言(VB,C)调用DLL是否正确工作?或者最好使用不同的名称制作两个函数?

附:这里有一些类似的问题(https://stackoverflow.com/questions/6257013/how-to-combine-overload-and-stdcall-in-delphi),但答案不适合我

P.S.S.烂英文

ADD(已在答案后添加)

显然,谢谢.

已经这样做了:

在项目中:

Function MyFunc (const X:Integer):string; StdCall; External 'MyDll.dll' Name 'MyFunc'; Overload;
Function MyFunc (const X:Extended):string; StdCall; External 'MyDll.dll' Name ' MyFunc1'; Overload;

在DllUnit1中

Exports
MyFunc (const X:Integer) Name 'MyFunc',MyFunc (const X:Extended) Name 'MyFunc1';

它编译并正常工作.

还是问题:

>喜欢作品,但它是否正确?
>是否有值如何写“Function MyFunc(const X:Integer):string; Overload; StdCall;”或“函数MyFunc(const X:Integer):string; StdCall; Overload;”?
>这个函数在其他语言的项目(Vb,C,C#)中会被正确引起吗?

解决方法

Means,DLL can export functions with identical names.

不,不是的. Delphi使用不同的参数声明InterlockedExchangeAdd()的2次重载,但kernel32.dll只导出一个InterlockedExchangeAdd()函数.两个Delphi声明正在导入相同的DLL函数.在运行时调用函数时,重载参数是等效的.换句话说,就函数而言,Addend:PLongint和var Addend:Longint是相同的.在运行时,它们都是指向Longint的指针.

第一个声明使用C风格的语法通过显式指针传递Addend参数:

var
  Value,Ret: Longint;
begin
  Ret := InterlockedExchangeAdd(@Value,1); 
end;

第二个声明使用Delphi风格的语法来代替通过引用传递Addend参数:

var
  Value,Ret: Longint;
begin
  Ret := InterlockedExchangeAdd(Value,1); 
end;

When you export an overloaded function or procedure from a dynamically loadable library,you must specify its parameter list in
the exports clause.

我从来没有在我的DLL中那样做,但是我也从不导出重载.指定参数允许编译器区分哪个导出使用哪个重载,但是如示例所示,这些重载由不同的名称导出,尽管它们在DLL的编码中使用相同的名称.

it is better to make two functions with different names?**

是.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读