- Код: Выделить всё
uses lua, lualib, lauxlib;
как начал просить dll. Не очень хочется таскать с собой dll. Есть вариант подключить lib файл lua или как-то по-другому убрать зависимость dll
Модератор: Модераторы
uses lua, lualib, lauxlib;
{$mode objfpc} {$h+}
{$linklib liblua53.a}
uses
SysUtils, ctypes;
const
LUA_OK = 0;
LUA_FIRSTPSEUDOIDX = -1001000;
LUA_REGISTRYINDEX = LUA_FIRSTPSEUDOIDX;
LUA_RIDX_MAINTHREAD = 1;
LUA_RIDX_GLOBALS = 2;
type
lua_State = record ptr: pointer; end;
lua_Alloc = function(ud: pointer; ptr: pointer; osize, nsize: csize_t): pointer; cdecl;
lua_Chunkreader = function(L: lua_State; ud: pointer; out sz: csize_t): pcchar; cdecl;
lua_CFunction = function(L: lua_State): cint; cdecl;
lua_KContext = PtrInt;
lua_KFunction = function(L: lua_State; status: cint; ctx: lua_KContext): cint; cdecl;
function lua_newstate(f: lua_Alloc; ud: pointer): lua_State; cdecl; external;
procedure lua_close(L: lua_State); cdecl; external;
function lua_load(L: lua_State; reader: lua_Chunkreader; dt: pointer; chunkname, mode: pcchar): cint; cdecl; external;
function lua_pcallk(L: lua_State; nargs, nresults, errfunc: cint; ctx: lua_KContext; k: lua_KFunction): cint; cdecl; external;
procedure lua_settop(L: lua_State; index: cint); cdecl; external;
procedure lua_pushlstring(L: lua_State; s: pcchar; ls: csize_t); cdecl; external;
procedure lua_pushcclosure(L: lua_State; fn: lua_CFunction; n: cint); cdecl; external;
procedure lua_rawgeti(L: lua_State; idx, n: cint); cdecl; external;
procedure lua_rawset(L: lua_State; idx: cint); cdecl; external;
function lua_tolstring(L: lua_State; idx: cint; out len: csize_t): pcchar; cdecl; external;
procedure lua_pushstring(L: lua_State; const s: string);
begin
lua_pushlstring(L, pcchar(s), length(s));
end;
function lua_tostring(L: lua_State; idx: cint): string;
var
p: pcchar;
len: csize_t;
begin
p := lua_tolstring(L, idx, len);
SetLength(result, len);
Move(p^, pointer(result)^, len * sizeof(result[1]));
end;
type
TLoadStringParam = record
s: pcchar;
rest: size_t;
end;
function LuaStringReader(L: lua_State; ud: pointer; out sz: csize_t): pcchar; cdecl;
var
p: ^TLoadStringParam absolute ud;
begin
result := pcchar(p^.s);
sz := p^.rest * sizeof(p^.s^);
p^.rest := 0;
end;
function lua_loadstring(L: lua_State; const s, name: string): cint;
var
p: TLoadStringParam;
begin
p.s := pcchar(s);
p.rest := length(s);
result := lua_load(L, @LuaStringReader, @p, pcchar(name), nil);
end;
function lua_pcall(L: lua_State; nargs, nresults, errfunc: cint): cint;
begin
lua_pcallk(L, nargs, nresults, errfunc, 0, nil);
end;
procedure lua_pop(L: lua_State; n: cint);
begin
lua_settop(L, -1 - n);
end;
function LuaAllocator(ud: pointer; ptr: pointer; osize, nsize: csize_t): pointer; cdecl;
begin
Assert(@ud = @ud); Assert(@osize = @osize);
result := ReallocMem(ptr, nsize);
end;
function LuaWriteln(L: lua_State): cint; cdecl;
begin
writeln(lua_tostring(L, 1));
result := 0;
end;
function ErrorFromMessage(L: lua_State): Exception;
begin
result := Exception.Create(lua_tostring(L, -1));
lua_pop(L, 1);
end;
procedure Main;
const
EOL = LineEnding;
Script =
'for i = 1, 10 do' + EOL +
' writeln("Test " .. i)' + EOL +
'end' + EOL +
EOL +
'return "string result"';
var
L: lua_State;
begin
L := lua_newstate(@LuaAllocator, nil);
if not Assigned(L.ptr) then
raise Exception.Create('Not enough memory for Lua state.');
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
lua_pushstring(L, 'writeln');
lua_pushcclosure(L, @LuaWriteln, 0);
lua_rawset(L, -3);
lua_pop(L, 1);
try
if lua_loadstring(L, Script, 'test') <> LUA_OK then
raise ErrorFromMessage(L);
if lua_pcall(L, 0, 1, 0) <> LUA_OK then
raise ErrorFromMessage(L);
writeln(lua_tostring(L, -1));
lua_pop(L, 1);
finally
lua_close(L);
end;
end;
begin
try
Main;
except
on E: Exception do writeln(E.Message);
end;
end.
runewalsh писал(а):Ээ, теоретически можешь сделать свой модуль из исходников этих, заменить «external %dllname%» на просто external, скомпилировать саму Луа GCC и подключить полученные .<какоетамрасширение> через {$LINKLIB %libname%}, практически скачай статическую библиотеку с https://sourceforge.net/projects/luabin ... es/Static/, попробуй скомпилировать, потупи в список ошибок линковки и покорно замени назад external на external 'lua53' и положи рядом DLL. Серьёзно, ни разу не удалось заставить эту линковку работать, хотя возможность выглядит привлекательной.
- Код: Выделить всё
{$mode objfpc} {$h+}
{$linklib liblua53.a}
uses
SysUtils, ctypes;
const
LUA_OK = 0;
LUA_FIRSTPSEUDOIDX = -1001000;
LUA_REGISTRYINDEX = LUA_FIRSTPSEUDOIDX;
LUA_RIDX_MAINTHREAD = 1;
LUA_RIDX_GLOBALS = 2;
type
lua_State = record ptr: pointer; end;
lua_Alloc = function(ud: pointer; ptr: pointer; osize, nsize: csize_t): pointer; cdecl;
lua_Chunkreader = function(L: lua_State; ud: pointer; out sz: csize_t): pcchar; cdecl;
lua_CFunction = function(L: lua_State): cint; cdecl;
lua_KContext = PtrInt;
lua_KFunction = function(L: lua_State; status: cint; ctx: lua_KContext): cint; cdecl;
function lua_newstate(f: lua_Alloc; ud: pointer): lua_State; cdecl; external;
procedure lua_close(L: lua_State); cdecl; external;
function lua_load(L: lua_State; reader: lua_Chunkreader; dt: pointer; chunkname, mode: pcchar): cint; cdecl; external;
function lua_pcallk(L: lua_State; nargs, nresults, errfunc: cint; ctx: lua_KContext; k: lua_KFunction): cint; cdecl; external;
procedure lua_settop(L: lua_State; index: cint); cdecl; external;
procedure lua_pushlstring(L: lua_State; s: pcchar; ls: csize_t); cdecl; external;
procedure lua_pushcclosure(L: lua_State; fn: lua_CFunction; n: cint); cdecl; external;
procedure lua_rawgeti(L: lua_State; idx, n: cint); cdecl; external;
procedure lua_rawset(L: lua_State; idx: cint); cdecl; external;
function lua_tolstring(L: lua_State; idx: cint; out len: csize_t): pcchar; cdecl; external;
procedure lua_pushstring(L: lua_State; const s: string);
begin
lua_pushlstring(L, pcchar(s), length(s));
end;
function lua_tostring(L: lua_State; idx: cint): string;
var
p: pcchar;
len: csize_t;
begin
p := lua_tolstring(L, idx, len);
SetLength(result, len);
Move(p^, pointer(result)^, len * sizeof(result[1]));
end;
type
TLoadStringParam = record
s: pcchar;
rest: size_t;
end;
function LuaStringReader(L: lua_State; ud: pointer; out sz: csize_t): pcchar; cdecl;
var
p: ^TLoadStringParam absolute ud;
begin
result := pcchar(p^.s);
sz := p^.rest * sizeof(p^.s^);
p^.rest := 0;
end;
function lua_loadstring(L: lua_State; const s, name: string): cint;
var
p: TLoadStringParam;
begin
p.s := pcchar(s);
p.rest := length(s);
result := lua_load(L, @LuaStringReader, @p, pcchar(name), nil);
end;
function lua_pcall(L: lua_State; nargs, nresults, errfunc: cint): cint;
begin
lua_pcallk(L, nargs, nresults, errfunc, 0, nil);
end;
procedure lua_pop(L: lua_State; n: cint);
begin
lua_settop(L, -1 - n);
end;
function LuaAllocator(ud: pointer; ptr: pointer; osize, nsize: csize_t): pointer; cdecl;
begin
Assert(@ud = @ud); Assert(@osize = @osize);
result := ReallocMem(ptr, nsize);
end;
function LuaWriteln(L: lua_State): cint; cdecl;
begin
writeln(lua_tostring(L, 1));
result := 0;
end;
function ErrorFromMessage(L: lua_State): Exception;
begin
result := Exception.Create(lua_tostring(L, -1));
lua_pop(L, 1);
end;
procedure Main;
const
EOL = LineEnding;
Script =
'for i = 1, 10 do' + EOL +
' writeln("Test " .. i)' + EOL +
'end' + EOL +
EOL +
'return "string result"';
var
L: lua_State;
begin
L := lua_newstate(@LuaAllocator, nil);
if not Assigned(L.ptr) then
raise Exception.Create('Not enough memory for Lua state.');
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
lua_pushstring(L, 'writeln');
lua_pushcclosure(L, @LuaWriteln, 0);
lua_rawset(L, -3);
lua_pop(L, 1);
try
if lua_loadstring(L, Script, 'test') <> LUA_OK then
raise ErrorFromMessage(L);
if lua_pcall(L, 0, 1, 0) <> LUA_OK then
raise ErrorFromMessage(L);
writeln(lua_tostring(L, -1));
lua_pop(L, 1);
finally
lua_close(L);
end;
end;
begin
try
Main;
except
on E: Exception do writeln(E.Message);
end;
end.
program test;
{$H+}
uses lua, lualib, lauxlib;
{$LINKLIB libimplua.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
begin
end.
program test;
{$H+}
uses lua, lualib, lauxlib;
//{$LINKLIB libimplua.a}
{$LINKLIB liblua53.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
begin
end.
runewalsh писал(а):А ты вызови что-нибудь, неиспользуемые функции не линкуются.
Для импорта из статической библиотеки нужна именно external без имени библиотеки, насколько я знаю (и линкер будет очень некрасиво ругаться без подсветки строки, если функцию не найдёт). А в этих модулях external LUA_NAME; — синтаксис для динамических.
program test;
{$H+}
uses lua, lualib, lauxlib;
{$LINKLIB libimplua.a}
//{$LINKLIB liblua53.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
function _luaL_newstate(): Plua_State; cdecl; external;
procedure _luaL_openlibs(L: Plua_State); cdecl; external;
procedure _lua_close(L: Plua_State); cdecl; external;
procedure Main;
var
L: Plua_State;
begin
L := luaL_newstate();
luaL_openlibs(L);
lua_close(L);
end;
begin
Main;
Write('Exit..');
Readln();
end.
vitya007 писал(а):Но все равно требует dll
procedure Main;
var
L: Plua_State;
begin
L := _luaL_newstate();
_luaL_openlibs(L);
_lua_close(L);
end;
скалогрыз писал(а):vitya007 писал(а):Но все равно требует dll
? в run-time что ли? или на стадии компоновки?
текст ошибки какой?
Вообще-то, согласно твоего объявления функций, код должен быть таким:
- Код: Выделить всё
procedure Main;
var
L: Plua_State;
begin
L := _luaL_newstate();
_luaL_openlibs(L);
_lua_close(L);
end;
иначе в поиске функции lua_newstate() он полезет в модули с загрузкой .dll-ки
program test;
{$H+}
uses lua, lualib, lauxlib;
{$LINKLIB libimplua.a}
//{$LINKLIB liblua53.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
function _luaL_newstate(): Plua_State; cdecl; external;
procedure _luaL_openlibs(L: Plua_State); cdecl; external;
procedure _lua_close(L: Plua_State); cdecl; external;
procedure Main;
var
L: Plua_State;
begin
L := _luaL_newstate();
_luaL_openlibs(L);
_lua_close(L);
end;
begin
Main;
Write('Exit..');
Readln();
end.
test.pas(27,16) Error: Undefined symbol: __luaL_newstate
test.pas(27,16) Error: Undefined symbol: __luaL_openlibs
test.pas(27,16) Error: Undefined symbol: __lua_close
vitya007 писал(а):Ошибок нету, но если сделать как ты говоришь, то получится вот это
program test;
{$H+}
uses lua, lualib, lauxlib;
{$LINKLIB libimplua.a}
//{$LINKLIB liblua53.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
function luaL_newstate(): Plua_State; cdecl; external;
procedure luaL_openlibs(L: Plua_State); cdecl; external;
procedure lua_close(L: Plua_State); cdecl; external;
procedure Main;
var
L: Plua_State;
begin
L := luaL_newstate();
luaL_openlibs(L);
lua_close(L);
end;
begin
Main;
Write('Exit..');
Readln();
end.
скалогрыз писал(а):runewalsh, проблемы с Си++ исключенияи из lua модулей решил как-нибудь?
скалогрыз писал(а):vitya007 писал(а):Ошибок нету, но если сделать как ты говоришь, то получится вот это
а вот это ожидаемый результат
попробуй так:
- Код: Выделить всё
program test;
{$H+}
uses lua, lualib, lauxlib;
{$LINKLIB libimplua.a}
//{$LINKLIB liblua53.a}
{$LINKLIB libimplualib.a}
{$LINKLIB libimplauxlib.a}
function luaL_newstate(): Plua_State; cdecl; external;
procedure luaL_openlibs(L: Plua_State); cdecl; external;
procedure lua_close(L: Plua_State); cdecl; external;
procedure Main;
var
L: Plua_State;
begin
L := luaL_newstate();
luaL_openlibs(L);
lua_close(L);
end;
begin
Main;
Write('Exit..');
Readln();
end.
test.pas(27,16) Error: Undefined symbol: _luaL_newstate
test.pas(27,16) Error: Undefined symbol: _luaL_openlibs
test.pas(27,16) Error: Undefined symbol: _lua_close
Дож писал(а):Так он же написан на С (а не С++) и "легковесно", какие там могут быть C++ исключения?
скалогрыз писал(а):vitya007 опубликуй где-нить .а файлы? (или сюда приаттачь)
vitya007 писал(а):Вообще они тут лежат "FPC\3.0.0\units\i386-win32\lua"
Вернуться в Free Pascal Compiler
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 61