Stdcall
не может использовать переменные аргументы. Любая функция C или C ++, принимающая переменные аргументы, должна иметь значение __cdecl
, поскольку только в этом соглашении о вызовах вызывающая программа (код), которая знает, сколько параметров было передано, очищает стек. Даже если соглашение о вызовах по умолчанию равно stdcall
, функции var args будут cdecl
.
Delphi не может генерировать таких функций, но может использовать существующие внешние функции C (в DLL или .obj-файле) с использованием директивы varargs
.
Итак, функция C (или C ++), такая как
HRESULT Invoke(void *pvReceiver, ...);
следует преобразовать в:
function Invoke(pvReceiver: Pointer); cdecl; varargs;
Обратите внимание, что вы опускаете часть ...
в декларации Delphi. Предполагается, когда вы используете директиву varargs
.
И это позволяет вам использовать его в Delphi, как в C или C ++:
Invoke(someReceiver, 17, 1.456);
Другой пример: например, хорошо известная функция C printf()
:
int printf(const char *format, ...);
объявлен как
function printf(format: PAnsiChar {args}): Integer; cdecl; varargs;
in System.Win.Crtl.pas .
Обновление
Кажется, это метод интерфейса.
Не уверен, что это работает, но я бы попробовал:
type
TInvoke = function(Intf: IInterface; pvReceiver: Pointer): HRESULT; cdecl varargs;
// No semicolon between cdecl and varargs.
и используйте его как:
MyResult := TInvoke(@myIntf.Invoke)(myIntf, someReceiver, 11, 17.3);
Этот метод может быть объявлен как __stdcall
(с помощью макроса STDMETHODCALLTYPE
), но даже тогда, если он вариационный, компилятор (VC ++) сгенерирует __cdecl
, как Реми Лебо обнаружил в Блог Раймонда Чена .