Ошибка загрузки DLL LuaJIT FFI

Я хочу закодировать некоторые функции на C для использования в Lua, и я думаю, что самый простой способ сделать это — использовать FFI LuaJIT.

У меня есть файл C "add.c":

int add(int a, int b){
return a+b;
}

Я собираю его в «add.o» с помощью:

gcc -c add.c

Делаю "add.dll":

gcc - shared -o add.dll add.o

Наконец, я пытаюсь запустить следующий код Lua в LuaJIT:

local ffi =require("ffi")

local test=ffi.load("C:\\users\\quebe\\Desktop\\add")

ffi.cdef[[
int add(int a,int b);
]]

print(test.add(1,2))

и получить:

luajit: test.lua:3: cannot load module 'C:\users\quebe\Desktop\add': %1 is 
not a valid Win32 application.

stack traceback:
    [C]: in function 'load'
    test.lua:3: in main chunk
    [C]: at 0x7ff72be120c0

но я понятия не имею, как интерпретировать это для отладки.


person CircArgs    schedule 13.08.2017    source источник
comment
Может попробовать add.dll вместо add?   -  person IS4    schedule 13.08.2017
comment
В документах говорится, что luajit.org/ext_ffi_api.html он будет искать .dll, но я даже пробовал .so (хотя я на windows) тоже безрезультатно.   -  person CircArgs    schedule 13.08.2017
comment
Я относительно новичок в C и особенно в динамических библиотеках. Я думаю, что пропустил что-то в сборке или что-то в сценарии C.   -  person CircArgs    schedule 13.08.2017
comment
Какую платформу вы используете? Винда, Линукс, что-то еще?   -  person Nicol Bolas    schedule 13.08.2017
comment
@CircArgs - Вы экспортировали функцию add из своей библиотеки?   -  person Egor Skriptunoff    schedule 13.08.2017
comment
@ Николь: Windows.   -  person CircArgs    schedule 13.08.2017
comment
@Егор Скриптунов - я не думаю, что сделал, поскольку все, что я сделал, находится в моем вопросе. Я думаю, что я что-то видел об этом, но у меня было какое-то впечатление, что это может быть специфично для компилятора. Не могли бы вы уточнить?   -  person CircArgs    schedule 13.08.2017
comment
@Егор Скриптунов - cygwin.com/cygwin-ug-net/dll.html Я следил за этим, в котором ничего не было об экспорте, поэтому я предполагаю, что это как-то связано с LuaJIT?   -  person CircArgs    schedule 13.08.2017
comment
Я бы предложил проверить, может ли ваша dll использоваться другой программой c. Быстрый гугл говорит, что процесс создания dll не совсем безмозглый: dll в gcc или cygwin"> stackoverflow.com/questions/6721364/   -  person Dimitry    schedule 13.08.2017
comment
@Dimitry, добавивший к функции префикс __declspec(dllexport), решил проблему. Я не уверен, что это так, но, поскольку ваш комментарий привел к решению, не могли бы вы отредактировать свой предыдущий ответ, и я могу его принять.   -  person CircArgs    schedule 14.08.2017


Ответы (2)


Согласно этому, перед загрузкой dll должно быть объявлено C-функция:

local ffi =require("ffi")
ffi.cdef[[
   int add(int a, int b)
]]
local test=ffi.load("C:\\users\\quebe\\Desktop\\add")

дополнение:

Кроме того, как упомянул Егор Скриптунов, функции внутри файла dll должны быть объявлены как экспортируемые. Подробности приведены в этом ответе SO.

person Dimitry    schedule 13.08.2017
comment
Спасибо за это. Я думаю, что это проблема, но, похоже, это не моя проблема. Я поместил его в код, и возникла та же ошибка, поэтому я думаю, что это проблема с созданием .dll? - person CircArgs; 13.08.2017
comment
Я использовал luajit только в Linux, на этом мой опыт заканчивается. Я добавлю несколько предложений по dll в комментариях к самому вопросу. - person Dimitry; 13.08.2017

Это похоже на то, что dll, которую вы пытаетесь загрузить, имеет зависимые dll, которые не могут быть загружены - обычно потому, что их нет в пути поиска Windows.

Идеи для решения:

  • Возьмите обходчик зависимостей и посмотрите на свою dll — отсутствующие обычно отмечены красным.
  • Часто, если вы строите с помощью Visual Studio, вам могут понадобиться среды выполнения Visual Studio, такие как vcp140.dll и vcr140.dll (или аналогичные). Иногда они неправильно зарегистрированы, и вам может потребоваться это сделать.
  • В Windows вы должны убедиться, что при сборке dll все функции экспортируются (это можно сделать несколькими способами — см. справку MSVC) и что они имеют искажение имени __stdcall или __cdecl. Без этого вы не сможете вызывать функции с помощью ffi.
  • Наконец, следите за безопасностью отключения DLL. Иногда DLL будут помечены как непригодные для использования в системе Win10. Проверьте свойства и включите dll. Обычно это происходит при копировании dll между определенными типами папок.
person David Lannan    schedule 07.09.2020