std :: bind не совместим с lua_call - PullRequest
3 голосов
/ 11 марта 2020

Использование библиотек разработки для Lua 5.3.5 и g cc 9.2.0 Я столкнулся со странной проблемой компиляции для следующего минимального фрагмента:

#include <functional>

extern "C" {
  #include "lua.h"
  #include "lualib.h"
}

int main()
{
  using namespace std::placeholders;

  auto lua_simple_call = std::bind(lua_call, _1, 0, 0);
}

g cc жалуется: error: ‘lua_call’ was not declared in this scope. Эта проблема не возникает при попытке просто вызвать lua_call без использования std::bind, и, похоже, она также не возникает для других Lua C функций, таких как lua_newtable et c. Я хотел бы знать, что вызывает это и как обойти это.

1 Ответ

7 голосов
/ 11 марта 2020

Как упоминалось в OP, lua_call - это макрос, который расширяется до lua_callk, но это только половина правды.

lua_call - это функция макрос:

github: lua.h:

#define lua_call(L,n,r)     lua_callk(L, (n), (r), 0, NULL)

, и это имеет значение.

Таким образом, lua_call расширится до lua_callk только при использовании с правильное количество аргументов.

Я сделал MCVE, чтобы продемонстрировать это:

#include <iostream>

#define lua_call(L, n, r) lua_callk(L, (n), (r))

void lua_callk(void *L, int n, int r)
{
  std::cout << "lua_callk(" << L << ", " << n << ", " << r << ")\n";
}

#define TEST(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  TEST(lua_call(nullptr, 2, 1));
  //TEST(std::cout << "&lua_call: " << &lua_call << '\n');
}

Вывод:

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
lua_call(nullptr, 2, 1);
lua_callk(0, 2, 1)

Live Demo on coliru

против:

#include <iostream>

#define lua_call(L, n, r) lua_callk(L, (n), (r))

void lua_callk(void *L, int n, int r)
{
  std::cout << "lua_callk(" << L << ", " << n << ", " << r << ")\n";
}

#define TEST(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  TEST(lua_call(nullptr, 2, 1));
  std::cout << "&lua_call: " << &lua_call << '\n');
}

Выход:

main.cpp: In function 'int main()':
main.cpp:15:34: error: 'lua_call' was not declared in this scope
   15 |   std::cout << "&lua_call: " << &lua_call << '\n';
      |                                  ^~~~~~~~

Живая демоверсия на coliru

или, чтобы сделать это еще более очевидным:

//#include <iostream>

#define lua_call(L, n, r) lua_callk(L, (n), (r))

void lua_callk(void *L, int n, int r)
{
  std::cout << "lua_callk(" << L << ", " << n << ", " << r << ")\n";
}

#define TEST(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  TEST(lua_call(nullptr, 2, 1));
  std::cout << "&lua_call: " << &lua_call << '\n';
}

с запуском только до процессора:

# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cpp"


void lua_callk(void *L, int n, int r)
{
  std::cout << "lua_callk(" << L << ", " << n << ", " << r << ")\n";
}


int main()
{
  std::cout << "lua_call(nullptr, 2, 1)" << ";\n"; lua_callk(nullptr, (2), (1));
  std::cout << "&lua_call: " << &lua_call << '\n';
}

Live Demo on coliru


Исправление также очевидно (как уже упоминалось в комментарии Rafix ):

Просто оберните lua_bind() в что-то адресуемое: функция или лямбда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...