【发布时间】:2020-04-01 15:00:38
【问题描述】:
我正在尝试将我的班级函数void write_log(String verbosity, Variant message); 传递给另一个将线程事件循环的班级(ev.h)。 String 和 Variant 来自 godot 命名空间。
我使用 typedef 将 write_log 转换为使用定义 typedef void (godot::MQTT::*Logger)(godot::String, godot::Variant); 的 Logger 类型。此定义存储在被调用者类中,而不是调用类中。
被调用的函数被定义为void initialize(Logger logger);,然后用下面的代码调用它。
libumqtt::Client client;
client.initialize(&MQTT::write_log);
我的调用类是godot::MQTT,被调用类是libumqtt::Client。
当我尝试使用 write_log 时出现错误。
void Client::initialize(Logger write_log) {
...
write_log("error", "Initializing MQTT Client!!! TypeDEF!!!");
...
}
错误信息如下。
➜ Godot-MQTT-Module git:(master) ✗ scons platform=osx bits=64
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o src/MQTT.os -c -g -O2 -arch x86_64 -std=c++17 -fPIC -I. -Igodot-cpp/godot_headers -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Isrc -Ilibraries/libumqtt/src src/MQTT.cpp
g++ -o src/client.os -c -g -O2 -arch x86_64 -std=c++17 -fPIC -I. -Igodot-cpp/godot_headers -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Isrc -Ilibraries/libumqtt/src src/client.cpp
src/client.cpp:120:14: error: called object type 'libumqtt::Client::Logger' (aka 'void (godot::MQTT::*)(godot::String, godot::Variant)') is not a function or function pointer
write_log("error", "Initializing MQTT Client!!! TypeDEF!!!");
~~~~~~~~~^
1 error generated.
scons: *** [src/client.os] Error 1
scons: building terminated because of errors.
我一直试图弄清楚为什么我不能让编译器识别函数指针,但到目前为止还没有这样的运气。我在弄乱我的代码时收到了诸如无法使用间接寻址等错误。
我还使用这些链接来帮助我学习如何使用 typedef 并传递函数指针:
- Typedef 带指针的完全限定名称 - http://www.radmangames.com/programming/how-to-use-function-pointers-in-cplusplus
- 使用 vs Typedef - https://www.internalpointers.com/post/differences-between-using-and-typedef-modern-c
- 标头中的类型定义 - How do I refer to a typedef in a header file?
- Typedef 示例 - https://en.wikipedia.org/w/index.php?title=Typedef&oldid=923023181#Function_pointers
- 什么是 Typedef - https://www.cprogramming.com/tutorial/typedef.html
- 传递函数指针 - https://stackoverflow.com/a/9413/6828099
编辑:关于未初始化的提到我的代码看起来正确,但发布的数量有限,我将链接粘贴到我的仓库中的类和头文件。这些链接是为这个特定的提交标记的,所以即使我更新代码,内容也不会改变。另外,这个库是 MIT 的,所以你不用担心版权问题。
编辑 2:使用this answer,我检查了我试图在被调用者类中使用write_log 的变量类型,它返回了我期望的值。所以,我不知道为什么编译器看不到这是一个函数。我正在使用 C++17 编译我的代码,而 C++14 也有同样的问题(C++11 甚至在到达此之前就中断了其他代码,因此它没有提供有用的结果)。
void (godot::MQTT::*)(godot::String, godot::Variant)
【问题讨论】:
-
不知道这样有没有帮助,但是原来的write_log函数在头文件中被标记为私有的。
-
我将函数标记为私有,因为从 write_log 调用的记录器类是从游戏引擎传入的。 logger 类是使用 GDScript 编写的。我试图传递给我的第二堂课的原始 write_log 工作得很好,它只是不能静态工作。
-
我设法让它工作。它与传递类本身的引用有关。我使用 std::invoke 来调用该函数。我稍后会发布我所做的,但是对于现在想查看的人,请查看此Github link。