Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Возврат String из FPC dll  [new]
Janex
Member

Откуда: Латвия
Сообщений: 1061
Привет всем.
Дёргаю из Delphi (10.3) приложения dll-кy написаную на FPC (3.х.х).
Передать String параметри В dll знаю как, но как обратно
получить String?

Примерно так на Delphi:
Type
  TMyFunction = function: PWideChar; CDecl;
Var 
  MyFunction :TMyFunction;

Function CallMyFunction: String;
begin 
  Result := ЧтоТоКакто(MyFunction);
end;

Примерно так на FPC:
Function MyFunction: PChar; Export; CDecl;
Var S :String;
Begin
  Result := ЧтоТоКакто(S);
End;

Что тук и как правильно делать?
Или хотябы как сделать процедуру где что то возврашается через входные параметри: "Var Argument :PWideChar" ?

WBR
Janex
11 янв 19, 09:23    [21782440]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25056
И туда и обратно нужно делать через выделенный заранее буфер, который уничтожается после вызова процедуры/функции.

Как это сделано в windows api.
11 янв 19, 09:30    [21782448]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
ziv-2014
Member

Откуда:
Сообщений: 235
Janex, Используй widestring и передавай в параметрах функции, и никогда не передавай в результате функции.
11 янв 19, 09:47    [21782463]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Фэйтл Эра
Member

Откуда:
Сообщений: 630
Janex
Привет всем.
Дёргаю из Delphi (10.3) приложения dll-кy написаную на FPC (3.х.х).
Передать String параметри В dll знаю как, но как обратно
получить String?

...

String - нельзя. Разные менеджеры памяти, возможно - разные реализации строк.

В функцию передавай указатель на буфер (PChar, например), в который функция должна упаковать результат.

// dll:
procedure GetMyF(var aStr : pChar; len : integer); export;
var
  fS : string;
begin
  fS := 'Привет'+ ', ' + 'Янекс!';
  CopyMemory(aStr, PChar(fS), Min(Length(fS) * SizeOf(Char) , len) - SizeOf(Char));
end;

//exe:
var
  fpStr: PChar;
begin
  fpStr := AllocMem(10);
  GetMyF (fpStr, 10);
  ShowMessage(fpStr);
  FreeMem(fpStr);



Или пусть буфер создается в dll, но тогда и dll пусть экспортирует функцию, освобождающую память буфера.

// dll:
function MyF() : PChar; export ;
var
  fS : string;
begin
  fS := 'Привет'+ ', ' + 'Янекс!';
  Result := AllocMem(Length(fS) * SizeOf(Char) + 1);
  CopyMemory(Result, PChar(fS), Length(fS) * SizeOf(Char));
end;

procedure FreeDllStr(aStr : PChar); export;
begin
  freeMem(aStr);
end;

// exe:
..
var
  fStr : pChar;

begin
  fStr := MyF();
  ShowMessage(fStr);
  FreeDllStr(fStr);
end;
11 янв 19, 10:45    [21782517]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Василий 2
Member

Откуда:
Сообщений: 433
WinAPI отличный пример для подражания. Есть как предвыделенные вызывателем буферы, так и выделение DLL-ю с последующим обязательным освобождением. Также есть режимы, возвращающие необходимую длину буфера.
11 янв 19, 10:55    [21782531]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Barlone
Member

Откуда:
Сообщений: 1119
Вот как раз с WideString все хорошо: достаточно использовать SysAllocString
11 янв 19, 13:13    [21782741]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Janex
Member

Откуда: Латвия
Сообщений: 1061
Фэйтл Эра,

Всё вроде как работает, спасибо, но некак немогу понять как и что в FPC делать чтоб
в дельфовскии екзешник передать юникод, типо UTF8.
Вот FPC:

Function  MyFunc: PUTF8Char; Export; CDecl;
Var S :UTF8String;
Begin
  S := 'Test test Женя';
  Result := AllocMem(Length(S) * SizeOf(UTF8Char) + 1);
  Move(PUTF8Char(S)^, Result^, Length(S) * SizeOf(UTF8Char));
end;   


Delphi екзешник:

Function Test: String;
Var S :PUTF8Char;
Begin
  s := MyFunc;
  Result :=  S;
End;



Там где "Test test" там всё прекрасно, а остальное крякобразы :(
Как правильно сморматировать, передать и отобразить UTF8 ?
13 янв 19, 20:46    [21784233]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Фэйтл Эра
Member

Откуда:
Сообщений: 630
Janex,

ну ты блин даешь. Отдаешь utf8 строку, а хочешь, чтобы она стала utf16. Сама собой она не перекодируется.
Перекодируй сам. Или в dll, или в exe.

Например, http://wiki.freepascal.org/Unicode_Support_in_Lazarus
13 янв 19, 21:26    [21784255]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Фэйтл Эра
Member

Откуда:
Сообщений: 630
Janex,

  Result := AllocMem(Length(S) * SizeOf(UTF8Char) + 1);

Я не уверен в правильности такого кода. Длина символа utf8 составляет от 1 до 4 байт:
https://ru.wikipedia.org/wiki/UTF-8
13 янв 19, 21:28    [21784257]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Гирлионайльдо
Member

Откуда:
Сообщений: 427
Фэйтл Эра,

Не бойся, больше 2 негров ещё нигде не используется.
14 янв 19, 00:55    [21784394]     Ответить | Цитировать Сообщить модератору
 Re: Возврат String из FPC dll  [new]
Василий 2
Member

Откуда:
Сообщений: 433
Фэйтл Эра
Janex,

  Result := AllocMem(Length(S) * SizeOf(UTF8Char) + 1);

Я не уверен в правильности такого кода. Длина символа utf8 составляет от 1 до 4 байт:
https://ru.wikipedia.org/wiki/UTF-8

В данном случае это нормально. Length(Utf8String) считает в байтах, а не символах
Janex
Там где "Test test" там всё прекрасно, а остальное крякобразы :(
Как правильно сморматировать, передать и отобразить UTF8 ?

Result := string(Utf8String(S));
14 янв 19, 10:14    [21784515]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить