在便携式应用程序C ++中包含Alien

时间:2012-01-09 01:53:20

标签: c++ winapi lua lua-alien

好的,我搜索了很多,但似乎无法找到答案或示例来说明如何实现这一点。

基本上,我有一个可移植的应用程序(在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))

我似乎无法找到办法做到这一点。我不想要求用户安装Lua for Windows,理想情况下,没有来自外星人的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包含在项目中,但似乎也没有这样做。

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

谢谢!

更新

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

显然,这可能是一个普遍的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,这似乎是我需要的最后一块。

再次感谢!     }

1 个答案:

答案 0 :(得分:1)

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

通过将alien直接链接到您的代码中,您可以避免使用动态库。但是内容枚举代码将不会运行,并且您无法使用require来运行它,否则它将寻找DLL文件(以及所有DLL依赖项)。

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