Не удается загрузить пакет разделяемой библиотеки (скомпилированный с помощью C ++ и Luabind) в Lua

Я скомпилировал общую библиотеку для примера "базовое использование" из документации Luabind. Однако я не могу вызвать его из Lua.

lbtest.cpp

extern "C"
{
    #include "lua.h"
}
#include <iostream>
#include <luabind/luabind.hpp>

void greet()
{
    std::cout << "hello world!\n";
}

extern "C" int init(lua_State* L)
{
    using namespace luabind;

    open(L);

    module(L)
    [
        def("greet", &greet)
    ];

    return 0;
}

Это компилируется в liblbtest.so. Однако, когда я запускаю команды (как описано в этом ответе)

> lua
> package.loadlib('liblbtest.so', 'init')()
> greet()

Я получаю такую ​​ошибку:

stdin: 1: попытка вызвать глобальное приветствие (нулевое значение), трассировка стека: stdin: 1: в основном блоке [C]:?

Я пробовал несколько тестов:

> fn, err = package.loadlib('liblbtest.so', 'init')
> print(fn)
nil

> fn, err = package.loadlib('liblbtest.so', 'init')()
stdin:1: attempt to call a nil value
stack traceback:
    stdin:1: in main chunk
    [C]: ?

> fn, err = package.loadlib('liblbtest.so', '_init')()
> print(fn)
nil

> fn, err = package.loadlib('liblbtest.so', '_init')
> print(fn)
function 0x1332e90

Все эти вызовы loadlib привели к одной и той же ошибке при вызове greet() (значение nil, как указано ранее). Интересно, что последний, по крайней мере, кажется, возвращает функцию.

Я запускаю Ubuntu 14.04 с Lua 5.1.5.

Как мне заставить это работать?


ОБНОВЛЕНИЕ

Мне удалось получить другую ошибку, когда я отбросил суффикс '.so' и начал использовать синтаксис require (согласно этот разговор в списке рассылки Lua)

> require('liblbtest')
error loading module 'liblbtest' from file './liblbtest.so':
    ./liblbtest.so: undefined symbol: luaopen_liblbtest
stack traceback:
    [C]: at 0x0047aff0
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: at 0x00406670

Однако, используя команду nm -gC liblbtest.so, я не вижу, чтобы этот символ был экспортирован. Как мне этого добиться?


person marcman    schedule 02.08.2016    source источник
comment
Используя ldd -r <yourobject> и (возможно) ldd -d <yourobject>, видите ли вы, что все экспортируется должным образом?   -  person M4rc    schedule 02.08.2016
comment
@ M4rc: Да. По крайней мере, я так считаю. Кажется, что все зависимости указывают на правильные каталоги. Я склоняюсь к мысли, что это меньше связано с моим общим объектом, а больше связано с тем, как я загружаю его в сценарий Lua. Но я готов ошибиться   -  person marcman    schedule 02.08.2016
comment
Если вы запустите readelf -Ws, видите ли вы там свою init функцию и greet функцию? AFAIK _init() может быть зарезервирован для точки входа C ++.   -  person M4rc    schedule 02.08.2016
comment
@ M4rc Я вижу приветствие как _ZL5greetv. Кажется, я вижу init как _ZStL8__ioint   -  person marcman    schedule 02.08.2016
comment
Я не могу полностью сбить с толку, что это такое - вы можете запустить c++filt _ZStL8__ioint, чтобы разобрать его на своей платформе. Я считаю, что это точка входа для инициализации stl, которая, вероятно, будет cout в вашем случае.   -  person M4rc    schedule 02.08.2016
comment
@ M4rc: Вы правы. Однако функция приветствия - это то, что я думал. Я нигде не вижу init явно   -  person marcman    schedule 02.08.2016
comment
просто из любопытства - поскольку я не очень хорошо знаком с LUA, можете ли вы объявить init функцию инициализации как угодно. Для ухмылки foo и попробуйте использовать package.loadlib('liblbtest.so', 'foo')(). Просто чтобы посмотреть, даст ли нам то, что мы ищем.   -  person M4rc    schedule 02.08.2016
comment
Если это все еще актуально, не могли бы вы показать, как вы компилируете свой модуль?   -  person n. 1.8e9-where's-my-share m.    schedule 27.06.2017


Ответы (1)


Ваша C DLL не соответствует формату lua C api DLL. Попробуйте: __declspec (dllexport) int luaopen_liblbtest (lua_State * L) {lua_register (L, "init", init); возврат 1; }

person Johnny    schedule 25.05.2017