delphi – 如何从DLL导出重载函数?
德尔福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的示例) ? 附:这里有一些类似的问题(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'; 它编译并正常工作. 还是问题: >喜欢作品,但它是否正确? 解决方法
不,不是的. 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;
我从来没有在我的DLL中那样做,但是我也从不导出重载.指定参数允许编译器区分哪个导出使用哪个重载,但是如示例所示,这些重载由不同的名称导出,尽管它们在DLL的编码中使用相同的名称.
是. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |