1

好的,我已经搜索了很多,但似乎无法找到如何实现这一目标的答案或示例。

基本上,我有一个设计为可移植的应用程序(在 VS2010 中使用 VC++ 构建,但没有 MFC 或托管组件,原始 WinAPI)。我在其中内置了 Lua 5.2,并允许用户在应用程序中编写脚本。我有多个粘合函数,这些函数暴露给处理各种 WinAPI 调用的 Lua 脚本。

但是,我想做的是允许用户编写一个看起来像这样的脚本:

require[[Alien/alien]]

local mb = alien.User32.MessageBoxA
mb:types{ 'long', 'long', 'string', 'string', 'long' }
print(mb(0, "Hello World!", "Test", 64))

我似乎根本找不到办法做到这一点。我不想要求用户为 Windows 安装 Lua,理想情况下,没有外星人的 core.dll 和 struct.dll;当我试图对 ./alien/ 中的那些 DLL 做一些事情时,它在 Lua5.1.dll 中崩溃了,因为我安装了 LuaForWindows,我卸载了 LFW,然后它只是说 Lua5.1.dll 丢失了。我在我的应用程序中内置了 Lua 5.2,所以很明显来自 Alien rock 的核心/结构 DLL 期望 Lua5.1.dll 在路径中。

我做了一个毫无价值的尝试,试图将 Alien src 包含到项目中,但似乎也没有那样工作。

任何想法将不胜感激。我希望它全部包含在我的应用程序中,但如果这是唯一的选择,我会选择一个解决方案,其中包括在我的项目中包含要构建和捆绑的库,并在分发中捆绑。

谢谢!

更新:

好的,谢谢本·沃伊特!我想我快到了。我已经引入 core.c 和 struct.c 并确保所有路径都用于 libffi。一切编译都没有问题,直到我尝试在 core.c(alien.core src 文件)中调用 luaopen_alien_core,声称标识符未声明。我试图在我试图进行调用的单独源文件中声明函数签名,编译得到进一步,但未能抱怨未解析的外部。

显然,这现在可能是一个普遍的 C++ 问题(因为我只是该领域的新手)。这是我所拥有的一般想法:

//core.c (from Alien project)

(...)

int luaopen_alien_core(lua_State *L) {
  alien_register_library_meta(L);
  alien_register_callback_meta(L);
  alien_register_function_meta(L);
  alien_register_buffer_meta(L);
  lua_getglobal(L, "alien");
  if(lua_isnil(L, -1)) {
    lua_newtable(L);
    lua_pushvalue(L, -1);
    lua_setglobal(L, "alien");
  }
  lua_newtable(L);
  lua_pushvalue(L, -1);
  lua_setfield(L, -3, "core");
  alien_register_main(L);
  return 1;
}

//mysource.c (the file attempting to call luaopen_alien_core(L))

void initLua()
{
    L = luaL_newstate();
    luaL_openlibs(L);
    luaopen_alien_core(L);
    (...)
}

这无法开始编译,发出错误:

error C3861: 'luaopen_alien_core': identifier not found

这是有道理的,所以我将以下行添加到 myheader.h:

int luaopen_alien_core(lua_State *L);

这可以编译,但无法链接:

error LNK2001: unresolved external symbol "int __cdecl luaopen_alien_core(struct lua_State *)" (?luaopen_alien_core@@YAHPEAUlua_State@@@Z)

以我有限的经验,我已经尝试了几件我能想到的事情,但没有什么能满足这个错误。我什至尝试将 core.c 的内容移动到 mysource.c 中,但这会造成完全不同的混乱,而且似乎是错误的方式。

我希望并想象这真的很愚蠢,但我只是不确定如何让它调用 luaopen_alien_core,这似乎是我需要的最后一块。

再次感谢!}

4

1 回答 1

1

我想该require指令既加载了一个动态库,又将其内容添加到了活动的 Lua 引擎中。

通过将外星人直接链接到您的代码中,您无需使用动态库。但是内容枚举代码不会运行,并且您不能使用require它来运行它,否则它将去寻找一个 DLL 文件(以及所有 DLL 依赖项)。

因此,您应该找出该require指令在加载 DLL 后调用的函数,并在创建 Lua 引擎时调用这些函数。然后脚本既不需要也不允许以 开头require [[Alien/alien]],但 Alien 对象将可用。

于 2012-01-09T05:10:51.777 回答