26

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

я это пробовал. и это не мое творение smile

27

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

sam063rus пишет:
ls_lib: array[0..2] of luaL_reg =

Кстати, выложенная dll с этим и скомпилирована.

28 (2016-09-29 11:31:27 отредактировано sam063rus)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

-

29 (2015-04-06 12:23:05 отредактировано merabn)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

sam063rus пишет:

увы, но код говорит другое. у вас там переделана и ещё с ошибками главная функция: luaopen_

Вы правы, наименования dll и функций я менял, как впрочем пытался менять в процессе еще много чего.
Не могу понять как вы увидели другое наименование экспортной функции, я смотрел несколькими просмотрщиками DLL, не нашел этого наименования, тем более в самом проекте стояло другое.
Но это не так важно, а важно что вы помогли разобраться в проблеме и я благодарю вас за это.
Delphi старших версий по-умолчанию используют Unicode. Теперь string и char в Unicode. В компиляторе нет опций для отключения Unicode и погуглив я нашел, что это нельзя сделать, если доверять специалистам, утверждающим это. Выход в переопределении всех строковых типов и переменных в функциях всех модулей: PChar в PAnsiChar, а string в ansistring. Я переопределил только используемые и все заработало.

sam063rus, не подскажете чем смотрели dll?
Еще раз спасибо.

30 (2016-09-29 11:31:36 отредактировано sam063rus)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

-

31

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

sam063rus пишет:

дизассемблером вестимо:))

Спасибо

32

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

А ведь sam063rus абсолютно прав, я совсем забыл про эту юникодную особенность новых дельфей, чем всё заметно осложняется.

Сделал проект на Delphi XE7. Перехачил все заголовочные файлы Lua под него.
Теперь собирается и работает как надо.

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

Скачать пример исходников DLL для Delphi XE7

33

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

Это всё замечательно, но как я могу из своей либы обратиться к методам в lua?

34 (2016-09-29 11:42:42 отредактировано sam063rus)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

-

35

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

Тогда еще вопрос, как я могу передать из DLL в LUA  строку?

36 (2016-09-29 11:42:32 отредактировано sam063rus)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

-

37

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

Да, действительно это так и работает) спасибо за помощь, предлагаю посмотреть, что получилось...
Теперь с помощью моей либы можно экспортировать данные по НТТР.
http://quik2dde.ru/viewtopic.php?id=160

Т.е. через нттр вызывать методы в LUA и получать результат

38 (2019-11-01 20:19:32 отредактировано toxa)

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

наваял, вот, для delphi/fpc хелперы, может кому пригодится. код раз в 10 более читаемый и безопасный.

unit LuaHelpers;

interface

uses 
  Classes, SysUtils,
  LuaLib;

type
  TLuaState     = LuaLib.lua_State;

  TLuaContext   = class;
  TLuaTable     = class;

  TLuaField     = class(tObject)
  private
    fContext    : TLuaContext;
    fFieldType  : integer;
    fNumber     : double;
    fBool       : boolean;
    fString     : ansistring;
    fTable      : TLuaTable;
    fIndex      : integer;

    function    getabsindex(AIndex: integer): integer;
    function    fExtractField(AIndex: integer): TLuaField;
    function    fGetField(AIndex: integer; const AName: ansistring): TLuaField;
  public
    constructor create(AContext: TLuaContext);
    destructor  destroy; override;
    function    AsBoolean(adefault: boolean = false): boolean;
    function    AsInteger(adefault: integer = 0): integer;
    function    AsNumber(adefault: double = 0.0): double;
    function    AsString(const adefault: ansistring = ''): ansistring;
    function    AsTable: TLuaTable;

    property    FieldType: integer read fFieldType;
    property    FieldByName[AIndex: integer; const AName: ansistring]: TLuaField read fGetField; default;
  end;

  TLuaTable     = class(tObject)
  private
    fContext    : TLuaContext;
    fField      : TLuaField;
    fIndex      : integer;
    fPopSize    : integer;
    fCurField   : TLuaField;
    fStackAlloc : boolean;

    function    getabsindex(AIndex: integer): integer;
    procedure   fSetIndex(AIndex: integer);
    function    fGetFieldByName(const AName: ansistring): TLuaField;
    function    fGetField: TLuaField;
    function    fGetSelf: TLuaTable;
  protected
    property    Field: TLuaField read fGetField;
  public
    constructor create(AContext: TLuaContext); overload;
    constructor create(AContext: TLuaContext; AIndex: integer); overload;
    constructor create(AContext: TLuaContext; ALuaTable: TLuaTable; const AName: ansistring); overload;
    constructor create(AContext: TLuaContext; const AGlobalName: ansistring); overload;
    destructor  destroy; override;

    function    FindFirst: boolean;
    function    FindNext: boolean;
    procedure   FindClose;

    function    FindField(const AName: ansistring): boolean;

    function    CallMethodSafe(const AName: ansistring; const AArgs: array of const; AResCount: integer; var error: ansistring; AResType: integer = LUA_TNONE): boolean;

    property    CurrentTable: TLuaTable read fGetSelf;
    property    Index: integer read fIndex write fSetIndex;
    property    FieldByName[const AName: ansistring]: TLuaField read fGetFieldByName; default;
    property    CurrentField: TLuaField read fCurField;
    property    Context: TLuaContext read fContext;
  end;

  TLuaContext   = class(tObject)
  private
    fLuaState   : TLuaState;
    fField      : TLuaField;
    function    fGetStackByIndex(AIndex: integer): TLuaField;
    function    fGetGlobalByName(const AName: ansistring): TLuaField;
    function    fGetSelf: TLuaContext;
  public
    constructor create(ALuaState: TLuaState);
    destructor  destroy; override;

    function    PushArgs(const aargs: array of const): integer;

    function    PushTable(aKVTable: tStringList): integer; overload;
    function    PushTable(const aargs: array of const): integer; overload;  // aargs must look like: ['name1', value1, 'name2', value2]

    function    Call(const AName: ansistring; const AArgs: array of const; AResCount: integer; AResType: integer = LUA_TNONE): boolean;
    function    CallSafe(const AName: ansistring; const AArgs: array of const; AResCount: integer; var error: ansistring; AResType: integer = LUA_TNONE): boolean;

    function    ExecuteSafe(const AScript: ansistring; AResCount: integer; var error: ansistring): boolean;

    procedure   CleanUp(ACount: integer);

    procedure   SetGlobal(AIndex: integer; const AName: ansistring);
    procedure   ResetGlobal(const AName: ansistring);

    property    CurrentContext: TLuaContext read fGetSelf;
    property    CurrentState: TLuaState read fLuaState;
    property    Stack[AIndex: integer]: TLuaField read fGetStackByIndex; default;
    property    Globals[const AName: ansistring]: TLuaField read fGetGlobalByName;
  end;

  TOnTableItemEx = function(ATable: TLuaTable): boolean of object;

implementation

function  StrToFloatDef(const astr: ansistring; adef: extended): extended;
begin if not TextToFloat(pAnsiChar(astr), result, fvExtended) then result:= adef; end;

{ TLuaField }

constructor TLuaField.create(AContext: TLuaContext);
begin
  inherited create;
  fContext:= AContext;
  fTable:= nil;
  fFieldType:= LUA_TNONE;
  fNumber:= 0;
  fBool:= false;
  setlength(fString, 0);
end;

destructor TLuaField.destroy;
begin
  if assigned(fTable) then freeandnil(fTable);
  inherited destroy;
end;

function TLuaField.getabsindex(AIndex: integer): integer;
begin
  if ((AIndex = LUA_GLOBALSINDEX) or (AIndex = LUA_REGISTRYINDEX)) then result := AIndex
  else if (AIndex < 0) then result := AIndex + lua_gettop(fContext.CurrentState) + 1
  else result := AIndex;
end;

function TLuaField.fExtractField(AIndex: integer): TLuaField;
var len : cardinal;
begin
  fFieldType:= lua_type(fContext.CurrentState, AIndex);
  case fFieldType of
    LUA_TNUMBER   : fNumber := lua_tonumber(fContext.CurrentState, AIndex);
    LUA_TBOOLEAN  : fBool := lua_toboolean(fContext.CurrentState, AIndex);
    LUA_TSTRING   : begin
                      len:= 0;
                      SetString(fString, lua_tolstring(fContext.CurrentState, AIndex, len), len);
                    end;
    LUA_TTABLE    : begin
                      if not assigned(fTable) then fTable:= TLuaTable.create(fContext, AIndex)
                                              else fTable.Index:= AIndex;
                    end;
    LUA_TFUNCTION : fIndex:= getabsindex(aindex);
    else            fFieldType:= LUA_TNONE;
  end;
  result:= Self;
end;

function TLuaField.fGetField(AIndex: integer; const AName: ansistring): TLuaField;
begin
  result:= Self;
  lua_pushstring(fContext.CurrentState, pAnsiChar(AName));
  lua_gettable(fContext.CurrentState, AIndex);
  try
    case lua_type(fContext.CurrentState, -1) of
      LUA_TTABLE : fFieldType:= LUA_TNONE;
      else         result:= fExtractField(-1) // only simple types allowed
    end;
  finally lua_pop(fContext.CurrentState, 1); end;
end;

function TLuaField.AsBoolean(adefault: boolean): boolean;
begin
  case fFieldType of
    LUA_TBOOLEAN : result:= fBool;
    LUA_TNUMBER  : result:= (fNumber <> 0);
    LUA_TSTRING  : result:= (AnsiCompareText(fString, 'TRUE') = 0);
    else           result:= adefault;
  end;
end;

function TLuaField.AsInteger(adefault: integer): integer;
begin result:= round(AsNumber(adefault)); end;

function TLuaField.AsNumber(adefault: double): double;
begin
  case fFieldType of
    LUA_TBOOLEAN : result:= integer(fBool);
    LUA_TNUMBER  : result:= fNumber;
    LUA_TSTRING  : result:= StrToFloatDef(fString, adefault);
    else           result:= adefault;
  end;
end;

function TLuaField.AsString(const adefault: ansistring): ansistring;
const boolval : array[boolean] of ansistring = ('FALSE', 'TRUE');
begin
  case fFieldType of
    LUA_TBOOLEAN : result:= boolval[fBool];
    LUA_TNUMBER  : result:= FloatToStr(fNumber);
    LUA_TSTRING  : result:= fString;
    else           result:= '';
  end;
end;

function TLuaField.AsTable: TLuaTable;
begin
  if (fFieldType = LUA_TTABLE) then result:= fTable
                               else result:= nil;
end;

{ TLuaTable }

constructor TLuaTable.create(AContext: TLuaContext);
begin
  inherited create;
  fContext:= AContext;
  fField:= nil;
  fCurField:= nil;
  fIndex:= 0;
  fStackAlloc:= false;
  fPopSize:= 0;
end;

constructor TLuaTable.create(AContext: TLuaContext; AIndex: integer);
begin
  inherited create;
  fContext:= AContext;
  fField:= nil;
  fCurField:= nil;
  fIndex:= getabsindex(AIndex);
  fStackAlloc:= false;
  fPopSize:= 0;
end;

constructor TLuaTable.create(AContext: TLuaContext; ALuaTable: TLuaTable; const AName: ansistring);
begin
  inherited create;
  fContext:= AContext;
  fField:= nil;
  fCurField:= nil;
  fIndex:= 0;
  fStackAlloc:= false;
  fPopSize:= 0;

  lua_pushstring(fContext.CurrentState, pAnsiChar(AName));
  lua_gettable(fContext.CurrentState, ALuaTable.Index);
  if lua_istable(fContext.CurrentState, -1) then begin
    fIndex:= getabsindex(-1);
    fStackAlloc:= true;
  end else begin
    lua_pop(fContext.CurrentState, 1);
    raise Exception.CreateFmt('Field %s is not a table', [AName]);
  end;
end;

constructor TLuaTable.create(AContext: TLuaContext; const AGlobalName: ansistring);
begin
  inherited create;
  fContext:= AContext;
  fField:= nil;
  fCurField:= nil;
  fIndex:= 0;
  fStackAlloc:= false;
  fPopSize:= 0;

  lua_getglobal(fContext.CurrentState, pAnsiChar(AGlobalName));
  if lua_istable(fContext.CurrentState, -1) then begin
    fIndex:= getabsindex(-1);
    fStackAlloc:= true;
  end else begin
    lua_pop(fContext.CurrentState, 1);
    raise Exception.CreateFmt('Global %s is not a table', [AGlobalName]);
  end;
end;

destructor TLuaTable.destroy;
begin
  if fStackAlloc then lua_pop(fContext.CurrentState, 1);
  fCurField:= nil;
  if assigned(fField) then freeandnil(fField);
  inherited destroy;
end;

function TLuaTable.getabsindex(AIndex: integer): integer;
begin
  if ((AIndex = LUA_GLOBALSINDEX) or (AIndex = LUA_REGISTRYINDEX)) then result := AIndex
  else if (AIndex < 0) then result := AIndex + lua_gettop(fContext.CurrentState) + 1
  else result := AIndex;
end;

procedure TLuaTable.fSetIndex(AIndex: integer);
begin fIndex:= getabsindex(AIndex); end;

function TLuaTable.fGetField: TLuaField;
begin
  if not assigned(fField) then fField:= TLuaField.create(fContext);
  result:= fField;
end;

function TLuaTable.fGetFieldByName(const AName: ansistring): TLuaField;
begin result:= Field.FieldByName[fIndex, AName]; end;

function TLuaTable.fGetSelf: TLuaTable;
begin result:= Self; end;

function TLuaTable.FindFirst: boolean;
begin
  FindClose;
  lua_pushnil(fContext.CurrentState);
  lua_pushnil(fContext.CurrentState);  // imitate "value"
  result:= FindNext;
end;

function TLuaTable.FindNext: boolean;
begin
  lua_pop(fContext.CurrentState, 1);   // pop previous "value"
  result:= (lua_next(fContext.CurrentState, Index) <> 0);
  if result then begin
    fCurField:= Field.fExtractField(-1);
    fPopSize:= 2;                      // leave "key" on stack, need to cleanup if findclose()
  end else begin
    fCurField:= nil;
    fPopSize:= 0;                      // no need to cleanup, stack is empty
  end;
end;

procedure TLuaTable.FindClose;
begin
  if (fPopSize > 0) then lua_pop(fContext.CurrentState, fPopSize);
  fPopSize:= 0;
end;

function TLuaTable.FindField(const AName: ansistring): boolean;
begin
  lua_pushstring(fContext.CurrentState, pAnsiChar(AName));
  lua_gettable(fContext.CurrentState, Index);
  fCurField:= Field.fExtractField(-1);
  fPopSize:= 1;
  result:= true;
end;

function TLuaTable.CallMethodSafe(const AName: ansistring; const AArgs: array of const; AResCount: integer; var error: ansistring; AResType: integer): boolean;
var len: cardinal;
begin
  if (AResCount < 0) then AResCount:= LUA_MULTRET;
  lua_getfield(fContext.CurrentState, Index, pAnsiChar(AName));
  lua_pushvalue(fContext.CurrentState, Index);
  fContext.PushArgs(AArgs);
  if (lua_pcall(fContext.CurrentState, length(aargs) + 1, AResCount, 0) = 0) then begin
    if (AResType <> LUA_TNONE) then begin
      result:= (lua_type(fContext.CurrentState, -1) = AResType);
      if not result and (AResCount > 0) then lua_pop(fContext.CurrentState, AResCount);
    end else result:= true;
  end else begin
    len:= 0;
    SetString(error, lua_tolstring(fContext.CurrentState, -1, len), len);
    lua_pop(fContext.CurrentState, 1);
    result:= false;
  end;
end;

{ TLuaContext }

constructor TLuaContext.create(ALuaState: TLuaState);
begin
  inherited create;
  fLuaState:= ALuaState;
  fField:= nil;
end;

destructor TLuaContext.destroy;
begin
  if assigned(fField) then freeandnil(fField);
  inherited destroy;
end;

function TLuaContext.fGetStackByIndex(AIndex: integer): TLuaField;
begin
  if not assigned(fField) then fField:= TLuaField.create(Self);
  result:= fField.fExtractField(AIndex);
end;

function TLuaContext.fGetGlobalByName(const AName: ansistring): TLuaField;
begin
  if not assigned(fField) then fField:= TLuaField.create(Self);
  lua_getglobal(fLuaState, pAnsiChar(AName));
  result:= fField.fExtractField(-1);  // may be problems with tables?
  lua_pop(fLuaState, 1);
end;

function TLuaContext.fGetSelf: TLuaContext;
begin result:= Self; end;

function TLuaContext.PushArgs(const aargs: array of const): integer;
var i : integer;
begin
  for i:= 0 to length(aargs) - 1 do begin
    with aargs[i] do begin
      case vType of
        vtInteger    : lua_pushinteger(fLuaState, vInteger);
        vtInt64      : lua_pushnumber(fLuaState, vInt64^);
        vtPChar      : lua_pushstring(fLuaState, pAnsiChar(vPChar));
        vtAnsiString : lua_pushstring(fLuaState, pAnsiChar(vAnsiString));
        vtExtended   : lua_pushnumber(fLuaState, vExtended^);
        vtBoolean    : lua_pushboolean(fLuaState, vBoolean);
        vtObject     : if assigned(vObject) then begin
                         if (vObject is tStringList) then PushTable(tStringList(vObject))
                                                     else lua_pushnil(fLuaState);
                       end else lua_pushnil(fLuaState);
        else           lua_pushnil(fLuaState);
      end;
    end;
  end;
  result:= length(aargs);
end;

function TLuaContext.PushTable(aKVTable: tStringList): integer;
var tmp : ansistring;
    p   : pAnsiChar;
    i   : integer;
begin
  result:= 0;
  if assigned(aKVTable) then with aKVTable do begin
    lua_createtable(fLuaState, Count, 0);
    for i := 0 to count - 1 do begin
      tmp:= Names[i];
      lua_pushstring(fLuaState, pAnsiChar(tmp));
      tmp:= Values[tmp];
      if (length(tmp) > 0) and (tmp[1]='"') then begin
        p:= pAnsiChar(tmp);
        tmp:= AnsiExtractQuotedStr(p, '"');
      end;
      lua_pushstring(fLuaState, pAnsiChar(tmp));
      lua_settable(fLuaState, -3);
    end;
    result:= 1;
  end;
end;

function TLuaContext.PushTable(const aargs: array of const): integer;
var i, count : integer;
begin
  count:= (length(aargs) div 2) * 2;                   // must be even, if not - last pair is not pushed!
  lua_createtable(fLuaState, count div 2, 0);
  for i:= 0 to count - 1 do begin
    with aargs[i] do
      case vType of
        vtInteger    : lua_pushinteger(fLuaState, vInteger);
        vtInt64      : lua_pushnumber(fLuaState, vInt64^);
        vtPChar      : lua_pushstring(fLuaState, pAnsiChar(vPChar));
        vtAnsiString : lua_pushstring(fLuaState, pAnsiChar(vAnsiString));
        vtExtended   : lua_pushnumber(fLuaState, vExtended^);
        vtBoolean    : lua_pushboolean(fLuaState, vBoolean);
        else           lua_pushnil(fLuaState);
      end;
    if (i mod 2 = 1) then lua_settable(fLuaState, -3); // set on every odd i
  end;
  result:= 1;
end;

function TLuaContext.Call(const AName: ansistring; const AArgs: array of const; AResCount: integer; AResType: integer): boolean;
begin
  if (AResCount < 0) then AResCount:= LUA_MULTRET;
  lua_getglobal(fLuaState, pAnsiChar(AName));                              // get function index
  PushArgs(aargs);                                                         // push parameters
  lua_call(fLuaState, length(aargs), AResCount);                           // call function
  if (AResType <> LUA_TNONE) then begin
    result:= (lua_type(fLuaState, -1) = AResType);
    if not result and (AResCount > 0) then lua_pop(fLuaState, AResCount);  // cleanup stack if unexpected type returned
  end else result:= true;
end;

function TLuaContext.CallSafe(const AName: ansistring; const AArgs: array of const; AResCount: integer; var error: ansistring; AResType: integer): boolean;
var len: cardinal;
begin
  if (AResCount < 0) then AResCount:= LUA_MULTRET;
  lua_getglobal(fLuaState, pAnsiChar(AName));                              // get function index
  PushArgs(aargs);                                                         // push parameters
  if (lua_pcall(fLuaState, length(aargs), AResCount, 0) = 0) then begin    // call function in "protected mode"
    if (AResType <> LUA_TNONE) then begin
      result:= (lua_type(fLuaState, -1) = AResType);
      if not result and (AResCount > 0) then lua_pop(fLuaState, AResCount);// cleanup stack if unexpected type returned
    end else result:= true;
  end else begin
    len:= 0;
    SetString(error, lua_tolstring(fLuaState, -1, len), len);
    lua_pop(fLuaState, 1);
    result:= false;
  end;
end;

function TLuaContext.ExecuteSafe(const AScript: ansistring; AResCount: integer; var error: ansistring): boolean;
var len: cardinal;
begin
  result:= (luaL_loadstring(fLuaState, pAnsiChar(AScript)) = 0);
  if result then begin
    result:= (lua_pcall(fLuaState, 0, AResCount, 0) = 0);
    if not result then begin
      len:= 0;
      SetString(error, lua_tolstring(fLuaState, -1, len), len);
      lua_pop(fLuaState, 1);
      result:= false;
    end;
  end else error:= 'Script loading failed';
end;

procedure TLuaContext.CleanUp(ACount: integer);
begin lua_pop(fLuaState, ACount); end;

procedure TLuaContext.SetGlobal(AIndex: integer; const AName: ansistring);
begin
  lua_pushvalue(fLuaState, AIndex);
  lua_setglobal(fLuaState, pAnsiChar(AName));
end;

procedure TLuaContext.ResetGlobal(const AName: ansistring);
begin
  lua_pushnil(fLuaState);
  lua_setglobal(fLuaState, pAnsiChar(AName));
end;

end.

примерно так может выглядеть обработчик колбэка OnQuote, при использовании хелперов, все потроха LUA скрываются:

function tSomeLuaClass.OnQuote(LuaState: TLuaState): Integer;
var classcode, seccode : ansistring;
  procedure dumptable(acontext: tLuaContext; atable: tLuaTable; const aparamname: ansistring);
  var rowtbl : tLuaTable;
  begin
    with TLuaTable.create(acontext, atable, aparamname) do try
      if FindFirst then try
        repeat
          if assigned(CurrentField) then begin
            rowtbl:= CurrentField.AsTable;
            if assigned(rowtbl) then 
              log('%s  price: %s qty: %s', [aparamname, rowtbl['price'].AsString, rowtbl['quantity'].AsString]);
          end;
        until not FindNext;
      finally FindClose; end;
    finally free; end;
  end;
begin
  with tLuaContext.create(LuaState) do try
    classcode := Stack[1].AsString;
    seccode   := Stack[2].AsString;
    log('OnQuote: Class: %s Code: %s', [classcode, seccode]);
    if Call('getQuoteLevel2', [classcode, seccode], 1, LUA_TTABLE) then try
      with Stack[-1].AsTable do begin
        if (FieldByName['bid_count'].AsInteger > 0) then
          dumptable(CurrentContext, CurrentTable, 'bid');
        if (FieldByName['offer_count'].AsInteger > 0) then
          dumptable(CurrentContext, CurrentTable, 'offer');
      end;
    finally CleanUp(1); end;
  finally free; end;
  result:= 0;
end;

39

Re: Создание своей DLL на Delphi или Lazarus для Lua (в QUIK)

Здравствуйте.
По Вашему описанию создания dll на lazarus сделал библиотеку. Все прекрасно работало. Под quik8.5.2(lua53) пытался изменить сам не получается. Спотыкается на luaL_openlib. По результатам поиска в инете пробовал заменить на
    luaL_setfuncs(L, @ls_lib, 0);
    lua_setglobal(L, PChar('MySoundLib'));
то же не правильно.
Что посоветуете?
(вместо 3-х файлов *.pas использовал lua53.pas)

Спасибо.