Тема: помогите подружить делфи с луа через длл

Уважаемые форумчане, помогите подружить делфи с луа через длл. 2 дня бьюсь по стопам здешних ребят ничего не получается. Брал сборку от 9 делфи, накатывал на неё луа 5.3.5 получал множество ошибок. Длл в результате моей правки просто не читает луа с ошибкой что дескать не является приложением вин 32.

2

Re: помогите подружить делфи с луа через длл

Давайте начнем с начала.
Какая версия Delphi?
Вы для QUIK это все делаете или для другой среды с Lua?

3 (2022-09-23 00:29:07 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

rad studio дельфи 11,квик

4 (2022-09-23 10:01:36 отредактировано swerg)

Re: помогите подружить делфи с луа через длл

bilobrovandrey пишет:

Длл в результате моей правки просто не читает луа с ошибкой что дескать не является приложением вин 32.

Даже не знаю, что-то где-то совсем пошло не так.
Как вариант - проверьте в свойствах проекта, вы dll генерируете 32 бина или 64 бита? QUIK у вас наверняка 64-битный, если версия его достаточно актуальная используется.

Вспоминал где же я на дельфи делал библиотеку для Lua5.3 / Lua5.4
Вспомнил: [url]https://github.com/swerg/QVCLua-0.5.0/tree/master/src[/url]
Там под Lazarus, но в любом случае заголовочные pas-файлы можно там взять для разных версий Lua, требуемую версию переключать параметрами сборки (как сделано в QVClua, например).

Re: помогите подружить делфи с луа через длл

Спасибо огромное за наводку, попробую за выхи разобраться.

6 (2022-09-24 12:18:34 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

спасибо за наводки!

Получилось.
Только  в результате переноса луа 5,3 вылезла куча ошибок в дельфи при компиляции. Частично поправил в силу своего понимания но многие пришлось просто скрыть в коде. Прошу помочь с их устранением если это возможно.
Моя ошибка заключалась в компилирование под 32 систему.
Пример работает, но в силу слабого понимания кода функции lua53 урезал.

7 (2022-09-24 17:21:06 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

а как в дельфи отобразить переменные из луа?
делаю переменную типа s:pansichar;
для луа 2 функции одна записывает в нее , вторая читает.
на когда я хочу дельфи ее прочитать из длл там либо нил либо любое значение присвоенное вне функций луа??
при этом в луа все работает как часы... всю голову изломал)
function str():pansichar;cdecl;
  begin
  result:=s;
  end;
   exports str;

8

Re: помогите подружить делфи с луа через длл

Не надо гадать.
Почитайте статьи про Lua API, посмотрите на пример на этой сайте, там есть пример функций принимающих/возвращающих значения.

Посмотрите на буквально соседнюю тему, там есть ссылки на статьи. Примеры обычно на Си, но это ж не проблема.

bilobrovandrey пишет:

function str():pansichar;cdecl;

Не пойму, это прототип функции, которая вызывается в DLL непосредственно из Lua?? Или что это?

Для функций, вызываемых в DLL из Lua, прототип всегда должен быть только таким:

function dll_function_for_lua(L: Plua_State): Integer; cdecl;

9 (2022-09-24 21:07:53 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

голова кругом) пожалуйста ткните носом  мне надо lua--> dll-->delphi обратка то у меня работает а вот выдернуть из длл переменную не получается(
вот 2 функции  записать считать строковый параметр.
s переменная где он хранится, ee хочу выденуть, но не получается
function forLua_str(L: Plua_State): Integer; cdecl;
var
    n,i: Integer;
    isNumberFound: Boolean;
    res:pansichar;
begin
   n := lua_gettop(L);  // количество переданных аргументов
   res := '';
   isNumberFound := false;
    for i := 1 to n do
      begin
        if lua_type(L,i) = LUA_TSTRING then
          begin
            res :=lua_tostring(L,i);
            isNumberFound := true;
          end;
      end;

    if isNumberFound then
       begin
       lua_pushstring(L, res);  // если найдено хоть однa строка в аргументах - возвращаем ее
       s:=res;
       end
    else
        lua_pushnil(L);         // если список аргументов пуст или в нем нет строк - функция вернет nil
      Result := 1;  // возвращаемое количество результатов
end;
     function forLua_rstr(L: Plua_State): Integer; cdecl;    //*чтение с переменной
  begin
if s<>nil then
       lua_pushstring(L,s)
       else lua_pushstring(L,pansichar('нет параметра')); // возвращаемое количество результатов
     Result := 1;
end;

10 (2022-09-24 22:22:54 отредактировано swerg)

Re: помогите подружить делфи с луа через длл

Какой тип переменной s ?

И еще.

res := '';

Странное место, ведь res - это указатель PAnsiChar

11 (2022-09-25 22:40:51 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

pansichar, возможно то что я задумал в принципе не возможно почитал тут умных людей;) получается что квик и делфи имеют разные области памяти в этой длл поэтому при обращение к одним и тем же переменным из дельфи и квика получаем разные данные. в этом случае фиаско) Мне нужно было именно передать из дельфи в луа и обратно данные.
пять раз перечитал ваш пост,правильно я понимаю, что переменная s не является данными записанными или считываемы в луа?
тогда мне надо писать процедуру по типу луа и как то выковыривать данные но уже для дельфи, хммм...

    function dll:PansiChar;stdcall
begin
Result:=lua_tostring(ldel,idel);
end;
exports dll;
разве вот такая функция не должна отдавать в дельфи значение строки в переменной?
хотя это масло масляное...

12 (2022-09-26 07:01:33 отредактировано swerg)

Re: помогите подружить делфи с луа через длл

swerg пишет:

Какой тип переменной s ?

bilobrovandrey пишет:

pansichar

PAnsiChar - это указатель. Указатель на память.
Вы вызовом  res :=lua_tostring(L,i); получили указатель в res, сохранили его в s. Но ведь по выходу из функции forLua_str() этот указатель становится уже невалидным.

Сделайте так:

var
   s: AnsiString;

И приведенный вами пример заработает.
Надо будет только поправить:
lua_pushstring(L,s) --> lua_pushstring(L,PAnsiChar(s))

13 (2022-09-27 00:09:51 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

вот интересно) а я уже через реестр заморочился ... причем выводит в реестр на ура, но если без костылей эт просто кайф получится,спасибо сейчас затестим....
на сколько я понял данная функция имеет отношение только к луа то есть она не забирает строку а наоборот отдает ее в луа.
работает  lua_tostring(L,i);(только при вызове из луа) где l указатель на переменную луа а i порядковый номер ее в стеке  отсюда сделал дельфи функцию которая просто заносит переменную в реестр виндовс . То есть я в луа вызываю функцию в длл которая с помощью дельфи функции заносит переменную в реестр)) если я из дельфи вызываю переменную в длл она просто пуста либо значение если ей задать то для дельфи луа его не меняет .печаль. тоска уныние.  остановлюсь тогда на реестре.

14

Re: помогите подружить делфи с луа через длл

Приведите полный текст библиотеки и ваш тестовый Lua-скрипт (или выложите куда-то).
Тогда можно было бы что-то прокомментировать из написанного вами.

15

Re: помогите подружить делфи с луа через длл

unit LuaFuncImpl;
interface

uses lua53, lauxlib, lualib,Registry;
  function forLua_str(L: Plua_State): Integer; cdecl;
  function forLua_rstr(L: Plua_State): Integer; cdecl;

var s:pansistring;
implementation

uses Windows, SysUtils;

procedure Regstring(name, param : string); // реестр  запись
var
  reg  : TRegIniFile;
begin
  reg := TRegIniFile.Create('');
  reg.RootKey := HKEY_LOCAL_MACHINE;
     //   добавляем
   try
   reg.WriteString('Software\Leopold',name,param) ;
   except    //если нет такого ключа создаем
    begin
    reg.CreateKey('Leopold');
    reg.WriteString('Software\Leopold',name,param) ;
    end;
   end;
  //освобождаем память
  reg.Free;
end;
function Regstringread(name : string):string; // реестр  чтение
var
  reg  : TRegIniFile;
begin
reg := TRegIniFile.Create('');
reg.RootKey := HKEY_LOCAL_MACHINE;
   try    //   читаем
   result:=reg.readString('Software\Leopold',name,'') ;
   except   //ловим
   result:='ошибка чтения реестра';
   end;
  //освобождаем память
reg.Free;
end;
function forLua_str(L: Plua_State): Integer; cdecl;//пишем строку в реестр пытаемся записать для дельфи в переменную
//первый  аргумент название второй строка
//вызываем в луа  названиедлл.str("имя параметра","значение")
var
    n,i: Integer;
    ISTRFOUND: Boolean;
    name,res: pansichar;

begin
   n := lua_gettop(L);  // количество переданных аргументов из луа
      ISTRFOUND := false;
    for i := 1 to n do
      begin
        if lua_type(L,i) = LUA_TSTRING then //проверка на стринг
          begin
            res :=lua_tostring(L,i); //записываем строку
            if i=1 then name:=res;//первай аргумент  имя в реестре
            ISTRFOUND := true; //если аргументов более 2х в принципе можно сделать мультизапись пока не нужно
          end;
      end;

    if ISTRFOUND then
       begin
         // если найдено хоть однa строка
       Regstring(name,res); //добавляем в реестр
       s:=pansistring(res);// лажа не работает
       //lua_pushstring(L,pansichar(s)) это пишет в луа по указателю l данные s
       end
      else
      lua_pushnil(L);// если список аргументов пуст или в нем нет строки - функция вернет nil
      Result := 1;  // возвращаемое количество результатов
end;

function forLua_rstr(L: Plua_State): Integer; cdecl;//*чтение с реестра переменной
//вызываем в луа  названиедлл.str("имя параметра")
     var n:integer;
  begin   //данная функция запишет параметр из реестра в луа
if lua_type(L,1) = LUA_TSTRING then //параметр из луа строка
lua_pushstring(L,Regstringread(lua_tostring(L,1)))//параметр будет являтся именем переменной в реестре
else lua_pushstring(L,pansichar('имя аргумента не является строкой'));// при ошибке возвращаем в луа
Result := 1;// возвращаемое количество результатов
end;
     function strtodelphi():string;stdcall //это вызываем из дельфи получаем строго 'неудача'
begin
if s<>nil then Result:=string(s) else result:='неудача';
end;
exports strtodelphi;
end.

через реестр все прекрасно вносится напрямую дельфи с длл читать не хочет
dll=require "SimpleDelphiLua"
local is_run = true
function onclose()
    is_run = false
end
function main()
    while is_run do
  wrreestr()
  sleep(3000)
    end
end

function wrreestr() -- запись текущих значен в реестр для обработки отображения параметров  для делфи
if dll.rstr('какоето_название')~='какая то строка' then
     dll.str('какоето_название','какая то строка')
end
end

16

Re: помогите подружить делфи с луа через длл

Я писал:

Сделайте так:

var
   s: AnsiString;

В вашем коде:

var s:pansistring;

"Как тебя понимать, Саид?" (с)

17

Re: помогите подружить делфи с луа через длл

function strtodelphi():string;stdcall //это вызываем из дельфи получаем строго 'неудача'
begin
if s<>nil then Result:=string(s) else result:='неудача';
end;
exports strtodelphi;

Этот кусок я не совсем понял.
А где осуществляется вызов strtodelphi?

18

Re: помогите подружить делфи с луа через длл

Действительно в горячке написал лишний букв)
стучусь головой об клаву)))

19 (2022-10-04 23:29:01 отредактировано bilobrovandrey)

Re: помогите подружить делфи с луа через длл

implementation

function strtodelphi():ansistring; external 'SimpleDelphiLua.dll' ;

procedure TForm1.buferDblClick(Sender: TObject);
begin
bufer.lines.add(string(strtodelphi));
end;

поправил ничего не изменилось
 
вызов осуществляется из проги дельфи

20

Re: помогите подружить делфи с луа через длл

Получается вы в два разных процесса подключаете одну DLL.
Но память-то у процессов разная же. Понятно, что значения, записанные в переменные в одном процессе, вы не прочитаете в другом.
Надо использовать какие-то хранилища, которые общие для разных процессов. (Например, вы использовали реестр)

21

Re: помогите подружить делфи с луа через длл

В любом случае спасибо огромное! задуманное мной работает, хоть и не так просто, как хотелось бы, - через реестр хотя бы нет ошибок записи это уже плюс.