Pergunta

Estou usando o Visual Studio 2005.

------------------------ [luapassing.cpp] ------------------ -

#include "lua.h"
static int myCfunc (Lua_State *L){
   double trouble = lua_tonumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
int luaopen_luapassing (Lua_State *L){
   static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
   luaL_register(L,"cstuff",Map);
   return;
}

------------------------- [csample.lua] ----------------- --------

package.cpath = "./CLua2.dll"
require "luapassing"

print("hola")
print(seth.doThis(120))
Foi útil?

Solução

Eu vejo vários problemas. Vou descrevê-los, e fornecer um fragmento de código que deve funcionar como eu acredito que você destina esse exemplo para trabalho.

O primeiro problema é que o compilador C ++ mutilado o nome da única função exportada de seu DLL cujas matérias nome à Lua: luaopen_luapassing(). A distribuição de ações binário para Windows foi compilado como um programa C, e assume um nome de estilo C para o ponto de entrada do módulo DLL.

Além disso, você tem o protocolo para a função luaopen_x ligeiramente errado. A função retorna um inteiro que conta Lua como muitos itens no topo da pilha de Lua são valores de retorno para uso por Lua. O protocolo assumido por require preferiria que você deixe tabela de objeto do novo módulo no topo da pilha e devolvê-lo à Lua. Para fazer isso, a função luaopen_x normalmente seria usar luaL_register() como você fez, em seguida, retornar 1.

Há também a questão da nomeação. Módulos escritos em puro Lua têm a oportunidade de estar menos conscientes de seus nomes. Mas módulos escritos em C tem que exportar uma função a partir da DLL que inclui o nome do módulo em seu nome. Eles também têm que fornecer esse nome módulo para luaL_register() para que a tabela direita é criado e atualizado no ambiente global. Finalmente, o script Lua cliente verá o módulo carregado em uma tabela global chamada como o nome passado para require, que também é retornado de require para que ele possa ser armazenado em cache em um local em que script.

Um par de outras lêndeas com o código C são de que o tipo numérico realmente deve ser escrito lua_Number para a portabilidade, e que seria convencional para usar luaL_checknumber() em vez de lua_tonumber() para reforçar o argumento necessário para a função. Pessoalmente, gostaria de citar a implementação C de uma função pública com um nome relacionado ao seu nome que será conhecido publicamente pela Lua, mas que é apenas uma questão de gosto.

Esta versão do lado do C deve corrigir esses problemas:

#include "lua.h"
static int my_dothis (Lua_State *L){
   lua_Number trouble = luaL_checknumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
    static const lua_reg Map [] = {
        {"dothis", my_dothis},
        {NULL,NULL}
    };
    luaL_register(L,"luapassing",Map);
    return 1;
}

O script de amostra, então, precisa para se referir ao módulo carregado pelo seu nome próprio, e para as funções definidas por esse módulo por seus nomes próprios. Lua é case sensitive, por isso, se o módulo cria uma função chamada dothis(), em seguida, o script deve usar o mesmo nome, e não pode encontrá-lo chamado doThis(), por exemplo.

require "luapassing"

print("hola")
print(luapassing.dothis(120))

Devo acrescentar que eu realmente não tenho compilado e executar o acima, então pode haver um erro de digitação ou dois deixada como um exercício; -)

Outras dicas

Se você vai estar fazendo um monte de C ++ para ligação lua, você pode querer dar uma olhada em luabind .

Se você está compilando como C ++ e quer combinar uma interface 'C', você deve declarar as funções visíveis externamente como extern "C" para citar evitar deturpação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top