使用 Lua 5.3.5 和 gcc 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);
}
Run Code Online (Sandbox Code Playgroud)
gcc 抱怨:error: ‘lua_call’ was not declared in this scope. 尝试在lua_call不使用的情况下简单调用时不会发生此问题,std::bind并且其他 Lua C 函数(如lua_newtable等)似乎也不会发生此问题。我想知道是什么导致了这种情况以及如何规避它。
正如 OP 所提到的,lua_call是一个扩展为的宏,lua_callk但这只是事实的一半。
lua_call是一个函数宏:
#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
Run Code Online (Sandbox Code Playgroud)
这就是区别。
因此,仅当与正确数量的参数一起使用时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');
}
Run Code Online (Sandbox Code Playgroud)
输出:
#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
Run Code Online (Sandbox Code Playgroud)
相对:
#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');
}
Run Code Online (Sandbox Code Playgroud)
输出:
#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');
}
Run Code Online (Sandbox Code Playgroud)
或者,为了使这一点更加明显:
//#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';
}
Run Code Online (Sandbox Code Playgroud)
仅使用预处理器运行:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
lua_call(nullptr, 2, 1);
lua_callk(0, 2, 1)
Run Code Online (Sandbox Code Playgroud)
修复也很明显(如Rafix 的评论中已经提到的):
只需包装lua_bind()成可寻址的东西:函数或 lambda。
| 归档时间: |
|
| 查看次数: |
63 次 |
| 最近记录: |