Как передать динамический массив строк в библиотеку DLL (DLL и клиент, написанный на d7) без ShareMem Unit? - PullRequest
8 голосов
/ 05 мая 2011

Я прочитал на этой странице, что для правильной работы динамических массивов необходим модуль ShareMem.

Однако я хотел бы написать открытое DLL для других языков.

Может кто-нибудь сказать мне, какя могу объявить функцию и ее параметры для передачи массива String?

Неужели что-то подобное не разрешено без ShareMem?

var
  templates : array of WideString;
begin
  SetLength(templates, 2); 
  templates[0] := 'template1';
  templates[1] := 'template2';
end
DLLFunction(@templates[0]); 

Спасибо за помощь!

1 Ответ

6 голосов
/ 05 мая 2011

Динамический массив строк - это уже массив PWideChar/PAnsiChar (для WideString or UnicodeString/AnsiString).

Этот динамический массив может быть напрямую отображен как есть, без копирования памяти, из большинства языков, как массив PWideChar/PAnsiChar:

От абонента:

DLLFunction(length(templates),pointer(templates)); 

От dll:

type
  TPAnsiCharArray = array[0..MaxInt div SizeOf(PAnsiChar)-1] of PAnsiChar;
  PPAnsiCharArray = ^TPAnsiCharArray;
  TPWideCharArray = array[0..MaxInt div SizeOf(PWideChar)-1] of PWideChar;
  PPWideCharArray = ^TPWideCharArray;

procedure DLLFunction(argc: integer; argv: PPWideCharArray);
var i: integer;
begin
  for i := 0 to argc-1 do
    writeln(argv[i]);
end;

Например, из библиотеки Cll можно использовать char **argv вместо PPAnsiCharArray и void **argv вместо PPWideCharArray.

Затем вы можете легко преобразовать обратно PWideChar/PAnsiChar в собственный тип строки языка.

Если вам нужно только написать DLL-файл Delphi, вы можете использовать

type
  TAnsiStringArray = array[0..MaxInt div SizeOf(AnsiString)-1] of AnsiString;
  PAnsiStringArray = ^TAnsiStringArray;
  TWideStringArray = array[0..MaxInt div SizeOf(WideString)-1] of WideString;
  PWideStringArray = ^TWideStringArray;

procedure DLLFunction(argc: integer; argv: PWideStringArray);
var i: integer;
begin
  for i := 0 to argc-1 do
    writeln(argv[i]);
end;

или даже

DLLFunction(templates);

procedure DLLFunction(const templates: array of WideString);
var i: integer;
begin
  for i := 0 to high(templates) do
    writeln(templates[i]);
end;
...