Delphi Xe.
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';
Means, DLL can export functions with identical names.
I try to repeat:
I create the project
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.
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.
…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.
But at compilation I receive an error: [DCC Error] DllUnit1.pas(7): E2273 No overloaded version of ‘MyFunc’ with this parameter list exists.
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.
Questions:
-
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)?
-
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. 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
P.S.S. Bad english
ADD (Has added after answers)
Clearly, thanks.
Has made so:
In the project:
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;
In DllUnit1
Exports
MyFunc (const X:Integer) Name 'MyFunc',
MyFunc (const X:Extended) Name 'MyFunc1';
It is compiled and works normally.
Still questions:
-
Like works, but whether it is correct?
-
Whether has value how to write “Function MyFunc (const X:Integer):string; Overload; StdCall;” or “Function MyFunc (const X:Integer):string; StdCall; Overload;”?
-
This functions in project of other languages (Vb, C ++, C #) will be correctly caused?
No, it does not. Delphi is declaring 2 overloads of
InterlockedExchangeAdd()with different parameters, but kernel32.dll only exports oneInterlockedExchangeAdd()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: PLongintandvar Addend: Longintare identical as far as the function is concerned. At runtime, they are both a pointer to aLongint.The first declaration uses a C-style syntax for passing the
Addendparameter by explicit pointer:The second declaration uses a Delphi-style syntax for passing the
Addendparameter by reference instead: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.
Yes.