Script.NET可以支持Lua脚本编辑调试,其中的Lua解释器插件内置的是Lua5.1.2版本的Lua动态库,但如果直接用相应的Lua动态库替换其中的动态库是无法运行的,原因是Script.NET使用的Lua库中增加了一个函数用于设置lua的库路径,Script.NET的Lua解释器插件调用此函数把lua库路径设置到Script.NET的Lua解释器目录的bin目录下。某些情况下如果想替换其中的lua动态库(例如自己修改了lua动态库来实现特殊功能),可以参考下面的方法,也就是把Script.NET修改的代码移植到自己定制的lua库中重新编译动态库。
lualib.h中增加如下代码:
/* set lua library path *add by blueant* */
LUALIB_API void (luaL_setlibpath) (lua_State *L, const char *path);
lualib.c中修改的代码(其中add by blueant部分是增加的):
static char g_lualibpath[MAX_PATH+1];
/* set lua library path *add by blueant* */
LUALIB_API void luaL_setlibpath (lua_State *L, const char *path) {
memset(g_lualibpath, 0, MAX_PATH+1);
strcpy(g_lualibpath, path);
}
#undef setprogdir
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n;
/add by blueant///
HKEY hKey;
LONG lRet;
DWORD dwType = REG_SZ;
DWORD dwSize = MAX_PATH;
// 首先判断是否设置了用于存储库路径的静态变量g_lualibpath,如果设置了就用这个变量
if(strlen(g_lualibpath) > 0)
{
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, g_lualibpath);
lua_remove(L, -2); /* remove original string */
return;
}
// 否则在注册表中查找Script.NET的安装路径
lRet = RegOpenKeyExA(HKEY_CURRENT_USER,
"Software//Blueant//Script.NET//2.0//Settings", 0, KEY_READ|KEY_QUERY_VALUE, &hKey);
if(lRet == ERROR_SUCCESS)
{
memset(buff, 0, MAX_PATH + 1);
lRet = RegQueryValueExA(hKey, "Install", NULL, &dwType, (LPBYTE)buff, &dwSize);
RegCloseKey(hKey);
}
if(lRet == ERROR_SUCCESS)
{
strcat(buff, "Interps//Lua//bin");
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
lua_remove(L, -2); /* remove original string */
return;
}
/
n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '//')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '/0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d/n", error);
}
static void ll_unloadlib (void *lib) {
FreeLibrary((HINSTANCE)lib);
}
static void *ll_load (lua_State *L, const char *path) {
HINSTANCE lib = NULL;
/add by blueant///
// 记录当前路径,并设置当前路径
char szOldPath[MAX_PATH+1];
char szdrive[MAX_PATH+1];
char szdir[MAX_PATH+1];
DWORD dwLen = 0;
memset(szOldPath, 0, MAX_PATH + 1);
dwLen = GetCurrentDirectory(255, szOldPath);
memset(szdrive, 0, MAX_PATH + 1);
memset(szdir, 0, MAX_PATH + 1);
_splitpath(path, szdrive, szdir, NULL, NULL);
strcat(szdrive, szdir);
SetCurrentDirectory(szdrive);
//
lib = LoadLibraryA(path);
add by blueant
SetCurrentDirectory(szOldPath);
//
if (lib == NULL) pusherror(L);
return lib;
}