gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 15:15:25 28 4
gpt4 key购买 nike

德尔福 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 Error] 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.

问题:

  1. 如何正确导出模块 DllUnit1 中的这些函数,以及是否可以在 Delphi 中进行一般操作(以一个名称导出),以从我的项目 TestMyDll 接收与一开始相同的调用(一个示例)来自 windows.pas)?

  2. 如果这样的函数可以以一个名称导出,那么通过其他语言(VB、C++)调用DLL是否可以正确工作?或者用不同的名称制作两个函数更好?

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

附注英语不好

<小时/>

添加(已在答案后添加)

显然,谢谢。

已经做到了:

在项目中:

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';

已编译并正常运行。

还有问题:

  1. 喜欢作品,但是否正确?

  2. “Function MyFunc (const X:Integer):string; Overload; StdCall;”的写法是否有值(value)或“Function MyFunc (const X:Integer):string; StdCall; Overload;”?

  3. 这个函数在其他语言(Vb、C++、C#)的项目中会正确出现吗?

最佳答案

Means, DLL can export functions with identical names.

不,事实并非如此。 Delphi 使用不同的参数声明了 2 个 InterlockedExchangeAdd() 重载,但 kernel32.dll 仅导出一个 InterlockedExchangeAdd() 函数。两个 Delphi 声明导入相同的 DLL 函数。重载参数与运行时调用函数时等效。换句话说,就功能而言,Addend: PLongintvar 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?**

是的。

关于delphi - 如何从DLL导出重载函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8583167/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com