Thread: Loadlib problems
Status: Alpha
Brought to you by:
cwalther
From: Andrea V. <and...@gm...> - 2008-05-19 13:05:36
|
Hi Chriss, I have tryed your example for luaplugin in the extras folder. I managed to build an addon.dll, but I have some problems. 1) I cannot understand how to link the dll, to access functions defined in pipmak.exe (like terminalPrintf in your example), so I comment out these. (but in this moment, access to these functions isn't fundamental for me) 2) I have successfully compiled you example after commented out call to terminalPrintf and after added definition #define LUA_API __declspec(dllexport) and postponing LUA_API to the init definition: LUA_API int init(lua_State *L) { .... } Without these steps I get an "procedure not found" during loadlib (Probably this is needed only with Windows and/or MSVC) Your example run correctly without any errors. 3) I have modified your example in this manner: ----------------------------------------------------- #define LUA_API __declspec(dllexport) #include <stdlib.h> #include <string.h> #include "lua.h" #include "lauxlib.h" static int greeting(lua_State *L) { lua_pushliteral(L, "Hello World!"); return 1; } typedef struct { char *greeting; } Greeter; static int newgreeter(lua_State *L) { const char *s; Greeter *greeter; if(lua_gettop(L)!=1) luaL_error(L, "wrong number of args"); s=luaL_checkstring(L, 1); greeter = lua_newuserdata(L, sizeof(Greeter)); luaL_getmetatable(L, "hello-greeter"); lua_setmetatable(L, -2); greeter->greeting = malloc(strlen(s) + 1); strcpy(greeter->greeting, s); return 1; } static int greeterCollect(lua_State *L) { Greeter *greeter = (Greeter*)luaL_checkudata(L, 1, "hello-greeter"); if (greeter == NULL) luaL_typerror(L, 1, "greeter"); free(greeter->greeting); return 0; } static int greeterGreeting(lua_State *L) { Greeter *greeter = (Greeter*)luaL_checkudata(L, 1, "hello-greeter"); if (greeter == NULL) luaL_typerror(L, 1, "greeter"); lua_pushstring(L, greeter->greeting); return 1; } static int luaGetProjectPath(lua_State *L) { if(lua_gettop(L)!=0) luaL_error(L, "no argument required"); lua_pushstring(L, "pipmak-projectpath"); lua_rawget(L, LUA_REGISTRYINDEX); return 1; } static const luaL_reg mylib[] = { {"getprojectpath", luaGetProjectPath}, {"newgreeter", greeterGreeting}, {"greeting", greeterGreeting}, {NULL, NULL} }; static const luaL_reg greeterMethods[] = { {"__gc", greeterCollect}, {"greeting", greeterGreeting}, {NULL, NULL} }; LUALIB_API int init(lua_State *L) { luaL_openlib(L,"tools",mylib, 0); luaL_newmetatable(L, "hello-greeter"); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); luaL_openlib(L, NULL, greeterMethods, 0); lua_pop(L, 1); /*greeter metatable*/ lua_pop(L,1); /*mylib */ return 0; } ----------------------------------------------------- As you can see, I have created a library "tools" so these functions are permitted: a) tools.greeting() b) tools.getprojectpath() c) tools.newgreeter("test") Well, (a) works fine (b) works fine if i cannot add any arguments, but if I write tools.getprojectpath(22) (I want to check luaL_error statement...) pipmak crash with this error: debug assertion failed dbgheap.c _CrtIsValidHeapPointer(pUserData) This may be due to a corruption of the heap, and indicates a bug in Pipmak.exe or any of the DLLs it has loaded. (c) always crash with the error above What is wrong? I think that my code is correct. Do you have any ideas? function init() is correct? Or i have to do something other to create library "tools"? Thank you for your hint. Andrea |
From: Christian W. <cwa...@gm...> - 2008-05-19 18:18:11
Attachments:
Pipmak.exe.a.bz2
|
Andrea Viarengo wrote: > 1) I cannot understand how to link the dll, to access functions defined > in pipmak.exe (like terminalPrintf in your example), so I comment out these. > (but in this moment, access to these functions isn't fundamental for me) It is important insofar as you need access to the Lua interpreter functions that are linked statically into Pipmak.exe, otherwise you need to link in an additional copy of Lua (I suppose that's what you've done, if it works for you). You need to link your plugin with Pipmak.exe.a, which is produced in the compilation of Pipmak with GCC (I don't know how you'd generate it when compiling Pipmak with MSVC, or if that is even possible). I have attached the version corresponding to the 0.2.7 release to this message. You may have to rename it to end in ".lib" for MSVC to recognize it as an import library. > 2) I have successfully compiled you example after commented out call to > terminalPrintf and after added definition > > #define LUA_API __declspec(dllexport) > > and postponing LUA_API to the init definition: > > LUA_API int init(lua_State *L) { > .... > } > > Without these steps I get an "procedure not found" during loadlib > (Probably this is needed only with Windows and/or MSVC) It worked for me with the GCC-cross-compiled version, so apparently GCC exported the function automatically. You could also do it using a .def file, I suppose. > As you can see, I have created a library "tools" > > so these functions are permitted: > > a) tools.greeting() > b) tools.getprojectpath() > c) tools.newgreeter("test") > > > Well, > > (a) works fine I can't test this since tools.greeting is greeterGreeting, which needs a greeter object, and you've left no way of creating any of those... When I reinsert newgreeter() into the library to create greeter objects, it works. > (b) works fine if i cannot add any arguments, but if I write > tools.getprojectpath(22) (I want to check luaL_error statement...) > > pipmak crash with this error: No crash for me, it works as intended both with and without arguments. > (c) always crash with the error above That's quite surprising since tools.newgreeter is the same C function as tools.greeting, which worked in (a). It works for me. Though tools.newgreeter("test") is not a valid call and rightfully complains "bad argument #1...". This is all on Mac OS X, I haven't tried on Windows. > What is wrong? I think that my code is correct. > Do you have any ideas? > function init() is correct? Or i have to do something other to create > library "tools"? Given these experiences, your code seems to be correct, and the problem apparenty lies in your build setup. Perhaps there's an incompatibility between the version of Lua contained in Pipmak.exe and the one you link into your plugin (assuming you do that)? Try again with Pipmak.exe.a, I'd say. -Christian |
From: Andrea V. <and...@gm...> - 2008-05-21 08:47:52
|
Hello, Christian Thank you for your quicky answer and your tests. It's true, the code that I have posted, wasn't correct.... I have send a wrong version, i'm apologize...: static const luaL_reg mylib[] = { {"getprojectpath", luaGetProjectPath}, //Single function (no methods) {"newgreeter", greeterGreeting}, //Constructor with methods {"greeting", greeting}, //Single function {NULL, NULL} }; util.greeting() correspond to tour greeting() and return just "Hello world!". I have done some investigation on internet, and I have discover that the behaviour I have described is caused by a BUG in the Windows version of lua interpreter: functions in the DLL allocate some memory in the stack of the interpreter. When the script finished, the interpreter will call lua_close(L) to release the resources. But it unload also the dll before clear the stack, so, the memory allocated in the DLL become invalid. Fortunately, this problem occurs only with the debugging versions of the libraries (first of all msvcrtd.lib and libcmtd.lib) Disabling all debug information and linking libraries without debugging info (msvcrt.lib and libcmt.lib) the problem disapear and all works FINE!!! I will put these infos on the wiki, if other people would realize plugins.. Now I want to try with your pipmak.exe.lib. Thank you!! Andrea |