Godot 4.1 GDExtension多C++源共享库问题:Summator无法调用
GDExtension整合Summator与Cppkinematics后Summator类无法调用
问题现象
基于Summator示例开发,新增Cppkinematics的C++源文件后,将两者整合到名为godotcppsharedlib的共享库中。GDScript可正常调用Cppkinematics类,但原Summator类无法使用,场景脚本报错:
Identifier Summator not declared in the current scope
疑似问题文件内容
game/bin/godotcppsharedlib.gdextension
[configuration] entry_symbol = "godotcppsharedlib_library_init" compatibility_minimum = 4.1 [libraries] windows.x86_64.debug = "res://bin/libgdgodotcppsharedlib.windows.template_debug.x86_64.dll" windows.x86_64.release = "res://bin/libgdgodotcppsharedlib.windows.template_release.x86_64.dll"
game.godot/extension_list.cfg
res://bin/godotcppsharedlib.gdextension
extension/src/register_types.cpp
#include "register_types.h" #include "summator.h" #include "cppkinematics.h" #include <gdextension_interface.h> #include <godot_cpp/core/class_db.hpp> #include <godot_cpp/core/defs.hpp> #include <godot_cpp/godot.hpp> using namespace godot; void initialize_summator_types(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } ClassDB::register_class<Summator>(); } void uninitialize_summator_types(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } } void initialize_cppkinematics_types(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } ClassDB::register_class<Cppkinematics>(); } void uninitialize_cppkinematics_types(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } } extern "C" { GDExtensionBool GDE_EXPORT godotcppsharedlib_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); init_obj.register_initializer(initialize_summator_types); init_obj.register_terminator(uninitialize_summator_types); init_obj.register_initializer(initialize_cppkinematics_types); init_obj.register_terminator(uninitialize_cppkinematics_types); init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); return init_obj.init(); } }
extension/src/register_types.h
#ifndef SUMMATOR_REGISTER_TYPES_H #define SUMMATOR_REGISTER_TYPES_H void initialize_summator_types(); void uninitialize_summator_types(); #endif // SUMMATOR_REGISTER_TYPES_H #ifndef CPPKINEMATICS_REGISTER_TYPES_H #define CPPKINEMATICS_REGISTER_TYPES_H void initialize_cppkinematics_types(); void uninitialize_cppkinematics_types(); #endif // CPPKINEMATICS_REGISTER_TYPES_H
SConstruct
#!/usr/bin/env python import os import sys env = SConscript("godot-cpp/SConstruct") env.Append(CPPPATH=["extension/src/"]) sources = Glob("extension/src/*.cpp") if env["platform"] == "macos": library = env.SharedLibrary( "game/bin/libgdgodotcppsharedlib.{}.{}.framework/godotcppsharedlib.{}.{}".format( env["platform"], env["target"], env["platform"], env["target"] ), source=sources, ) else: library = env.SharedLibrary( "game/bin/libgdgodotcppsharedlib{}{}".format(env["suffix"], env["SHLIBSUFFIX"]), source=sources, ) Default(library)
问题根源
register_types.h中声明的初始化/终止函数与register_types.cpp中的定义参数不匹配:
- 头文件中函数声明为无参数(如
void initialize_summator_types();) - 源文件中函数定义携带
ModuleInitializationLevel参数(如void initialize_summator_types(ModuleInitializationLevel p_level))
这种不匹配会导致编译器将声明与定义视为两个完全不同的函数,初始化流程中实际调用的是未实现的无参数版本,而真正执行Summator注册逻辑的带参数函数从未被调用,最终导致Summator类未注册到Godot的ClassDB中。
解决方案
- 修正
register_types.h中的函数声明,为所有初始化/终止函数添加godot::ModuleInitializationLevel参数:
#ifndef SUMMATOR_REGISTER_TYPES_H #define SUMMATOR_REGISTER_TYPES_H void initialize_summator_types(godot::ModuleInitializationLevel p_level); void uninitialize_summator_types(godot::ModuleInitializationLevel p_level); #endif // SUMMATOR_REGISTER_TYPES_H #ifndef CPPKINEMATICS_REGISTER_TYPES_H #define CPPKINEMATICS_REGISTER_TYPES_H void initialize_cppkinematics_types(godot::ModuleInitializationLevel p_level); void uninitialize_cppkinematics_types(godot::ModuleInitializationLevel p_level); #endif // CPPKINEMATICS_REGISTER_TYPES_H
- 重新编译共享库:执行
scons命令重新构建扩展库。 - 重启Godot编辑器,刷新场景脚本,验证Summator类是否可正常调用。
内容的提问来源于stack exchange,提问作者Pansophical T
相关产品推荐
相关产品推荐

