Вызывать переменную C-функцию по ее адресу памяти в Delphi - PullRequest
2 голосов
/ 27 января 2010

Предположим, у меня есть функция в C ++, в которой я вызываю ее, используя указатель на адрес своей памяти, с typedef.Теперь, как я могу сделать то же самое в Delphi?

Например:

typedef void (*function_t)(char *format, ...);
function_t Function;
Function = (function_t)0x00477123;

И затем я могу вызвать его с помощью: Function("string", etc);.

IsЕсть ли способ сделать это, не используя инструкции по сборке, в Delphi?

Обратите внимание, что это функция с переменными параметрами.

Ответы [ 3 ]

17 голосов
/ 28 января 2010

Идиоматический перевод для этого:

typedef void (*function_t)(char *format, ...);
function_t Function;
Function = (function_t)0x00477123;

Это:

type
  TFunction = procedure(Format: PAnsiChar) cdecl varargs;
var
  Function: TFunction;
// ...
  Function := TFunction($00477123);

'cdecl varargs' требуется для получения соглашения о вызовах C (где вызывающий объект извлекает стек) и поддержки переменных аргументов (что поддерживается только соглашением о вызовах C) Varargs поддерживается только как средство для вызова C; в Delphi нет встроенной поддержки для реализации списков переменных параметров в стиле C. Вместо этого есть другой механизм, используемый процедурой Format и друзьями:

function Format(const Fmt: string; const Args: array of const): string;

Но вы можете узнать больше об этом в другом месте.

2 голосов
/ 27 января 2010
program Project1;

type
  TFoo = procedure(S: String);

var
  F: TFoo;
begin
  F := TFoo($00477123);
  F('string');
end.

Конечно, если вы просто запустите приведенное выше, вы получите ошибку времени выполнения 216 по адресу $ 00477123.

1 голос
/ 27 января 2010

Да, Delphi поддерживает указатели функций. Объявите это так:

type MyProcType = procedure(value: string);

Затем объявите переменную типа MyProcType и присвойте ей адрес вашей процедуры, и вы можете вызывать ее так же, как в C.

Если вы хотите указатель на метод объекта вместо отдельной процедуры или функции, добавьте « объекта » в конец объявления указателя функции.

...