【问题标题】:How to combine overload and stdcall in Delphi?如何在 Delphi 中结合重载和 stdcall?
【发布时间】:2011-06-06 19:31:29
【问题描述】:

我有一个导出这个函数的 SOAP 数据模块

function MyFunction(MyParam1, MyParam2): boolean; stdcall;

我可以从另一个 exe 中使用此功能。一切正常。

现在我想在它所在的同一个项目中使用相同的函数。我将它的单元添加到 uses 子句但它没有识别它(我得到了未声明的标识符)。然后我添加了一个重载,但我无法让它工作。

function MyFunction(MyParam1, MyParam2): boolean; stdcall; overload;
function MyFunction(MyParam1, MyParam2): boolean; overload;

我得到“不允许的字段定义...”

我希望能够使用 stdcall 从外部访问该函数,但也希望能够在内部访问该函数,如常见的库函数调用。有谁知道我怎样才能做到这一点?

【问题讨论】:

  • 不可能,overload 在参数列表上有所不同(顺便说一句,你有语法错误),但在返回类型或调用约定上没有变化。
  • 你不能在项目中也使用stdcall 版本吗?

标签: delphi delphi-7


【解决方案1】:

您的问题与调用约定无关。

需要注意的几点:

一个愚蠢的错误

首先,

function MyFunction(MyParam1, MyParam2): boolean; stdcall;

是语法错误。您忘记指定MyParam1MyParam2 的类型。

可见性

考虑单位

  unit Unit1;

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs;

  function Func1(MyParam1, MyParam2: integer): boolean;

  implementation

  function Func1(MyParam1, MyParam2: integer): boolean;
  begin
    ShowMessage('Func1');
  end;

  function Func2(MyParam1, MyParam2: integer): boolean;
  begin
    ShowMessage('Func2');
  end;

  end.

只有Func1 对其他单位可见,因为只有Func1interface 部分中声明。而界面就是其他单位看到的。

调用约定

您可以在自己的项目中使用stdcall。这根本不是问题。您甚至可能不会注意到该函数具有“不寻常”的调用约定。

重载函数

一对重载函数(过程)是一对同名但有不同参数列表的函数(过程),如

function Add(A, B: integer): integer; overload;
function Add(A, B: real): real; overload;

两个函数不能有相同的名称和参数列表,即使它们被重载。确实,如果允许的话,那么编译器怎么会知道你要调用什么函数呢?!

【讨论】:

  • 关于 stdcall 和性能的注意事项:C++ 中的注册约定名称为 __fastcall,它不仅仅是一个随机名称,stdcall 更慢。
  • @user MS fastcall != Borland fastcall,又名注册。
【解决方案2】:

您提供的代码无法编译,因为您没有指定参数类型。如果您这样做,那么只要参数列表不同,它就可以正常工作。

例如,这编译得很好:

function MyFunction(MyParam1, MyParam2: Integer): boolean; stdcall; overload;
function MyFunction(MyParam1, MyParam2: Double): boolean; overload;

但这不是:

function MyFunction(MyParam1, MyParam2: Integer): boolean; stdcall; overload;
function MyFunction(MyParam1, MyParam2: Integer): boolean; overload;

重载是指您拥有多个名称相同但参数列表不同的方法。每当您调用重载方法时,编译器都会选择参数列表与所传递参数匹配的方法。


我怀疑您试图重载该方法,对方法的两个版本使用相同的参数列表,但调用约定不同。这行不通。重载的方法解析不能基于调用约定(或函数返回值类型)来执行。只需在内部和外部使用stdcall 版本即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多