如何从DLL导出重载函数? [英] How to export Overload functions from DLL?

查看:144
本文介绍了如何从DLL导出重载函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Delphi Xe。

Delphi Xe.

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

In module Windows.pas I see one of methods:

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可以导出具有相同名称的函数。

Means, DLL can export functions with identical names.

我尝试重复:

我创建项目

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:

It is compiled normally. Further I create DLL:

Library MyDll;

uses
  SimpleShareMem,
  DllUnit1 in 'DllUnit1.pas';

{$R *.res}

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

...和模块DllUnit1.pas

...and module 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'重载版本

But at compilation I receive an error: [DCC Error] DllUnit1.pas(7): E2273 No overloaded version of 'MyFunc' with this parameter list exists.

在Delphi帮助中,我看到:

In Delphi Help, I see:

"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)?

  1. How correctly to export these functions in module DllUnit1 and whether it is possible to make it in general in Delphi (export under one name) to receive the same call from the my project TestMyDll as in the beginning (an example from windows.pas)?

如果可以使用一个名称导出此类函数,则通过从其他语言调用DLL来工作是否正确(VB ,C ++)?还是使两个函数具有不同的名称更好?

If such functions can be exported under one name, whether that it will be correct to work by call DLL from other languages (VB, C ++)? Or it is better to make two functions with different names?

P.S。在这里发现了一些类似的问题(http://stackoverflow.com/questions/6257013/how-to-combine-overload-and-stdcall-in-delphi),但是答案不适合我

P.S. Little bit similar question has found here (http://stackoverflow.com/questions/6257013/how-to-combine-overload-and-stdcall-in-delphi), but the answer did not suit me

PSS英语不好

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

它已编译并可以正常工作。

It is compiled and works normally.

仍然存在问题:


  1. 像工程一样,但是否正确?

  1. Like works, but whether it is correct?

如何编写 Function MyFunc(const X:Integer):string; Overload; StdCall;是否有价值?或 Function MyFunc(const X:Integer):string; StdCall; Overload;?

Whether has value how to write "Function MyFunc (const X:Integer):string; Overload; StdCall;" or "Function MyFunc (const X:Integer):string; StdCall; Overload;"?

此函数在其他语言的项目中起作用(Vb,C ++) ,C#)是否会正确引起?

This functions in project of other languages (Vb, C ++, C #) will be correctly caused?


推荐答案


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

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

No, it does not. Delphi is declaring 2 overloads of InterlockedExchangeAdd() with different parameters, but kernel32.dll only exports one InterlockedExchangeAdd() function. The two Delphi declarations are importing the same DLL function. The overloaded parameters are equivilent when calling the function at runtime. In other words, Addend: PLongint and var Addend: Longint are identical as far as the function is concerned. At runtime, they are both a pointer to a Longint.

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

The first declaration uses a C-style syntax for passing the Addend parameter by explicit pointer:

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

第二个声明使用Delphi样式的语法传递 Addend

The second declaration uses a Delphi-style syntax for passing the Addend parameter by reference instead:

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




从动态导出重载函数或过程时可加载的库,必须在
exports子句中指定其参数列表。

我从不需要在我的DLL中执行此操作,但随后我也永远不会导出重载。指定参数可以使编译器区分哪个导出使用哪个重载,但是如该示例还显示,尽管这些重载在DLL的编码中使用相同的名称,但它们是通过不同的名称导出的。

I have never had to do that in my DLLs, but then I never export overloads, either. Specifying the parameters allows the compiler to differentiate which export uses which overload, but as the example also shows, those overloads are exported by different names, though they use the same name in the DLL's coding.


最好使两个函数具有不同的名称?**

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

是。

这篇关于如何从DLL导出重载函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆