godot-cpp 4.1, compilation error and how to fix it?
Asked Answered
F

2

0

I'm working on my first Godot 4.1 extension with GDExtension. I don't really know C++, I'm mostly a Golang and Python developer. Currently, I'm facing a challenge: I want to use a custom type as return for a method you should be able to use in GDScript, and I'm unsure how to proceed. This custom type is simply a struct that inherits from godot::Object:

// poker.hpp
struct SingleHandRankingEvaluationResult : public godot::Object {
  GDCLASS(SingleHandRankingEvaluationResult, godot::Object);

private:
  int HandRanking;
  godot::String Error;

protected:
  static void _bind_methods();

public:
  void setHandRanking(int ranking);
  int getHandRanking();
  void setError(godot::String error);
  godot::String getError();
};

class Poker : public godot::Object {
  GDCLASS(Poker, godot::Object);

protected:
  static void _bind_methods();

public:
  static godot::PackedStringArray getDeck();
  static godot::PackedStringArray getDeckShuffled();
  SingleHandRankingEvaluationResult
  singleHandRankEvaluation(const godot::PackedStringArray cards);
  // ... other unrelated functions
};

And the error I'm seeing when compiling is the following:

➜  scons
scons: Reading SConscript files ...
Auto-detected 12 CPU cores available for build parallelism. Using 11 cores by default. You can override it with the -j argument.
Building for architecture x86_64 on platform linux
scons: done reading SConscript files.
scons: Building targets ...
scons: `godot-cpp/bin/libgodot-cpp.linux.template_debug.x86_64.a' is up to date.
g++ -o godot/poker.os -c -std=c++17 -fPIC -Wwrite-strings -m64 -march=x86-64 -O2 -fPIC -DLINUX_ENABLED -DUNIX_ENABLED -DDEBUG_ENABLED -DDEBUG_METHODS_ENABLED -DNDEBUG -Igodot-cpp/gdextension -Igodot-cpp/include -Igodot-cpp/gen/include -I/nix/store/5hch4vqzwan8ksab4pfpyrbb7wvvv3ad-cxxtest-4.4/include -I/nix/store/7nbh3b6hhjqjs3nfy529g38l85iv46i9-openssl-3.0.11-dev/include -Isrc -Iompeval/omp -Igodot godot/poker.cpp
In file included from godot/../godot-cpp/include/godot_cpp/core/class_db.hpp:38,
                 from godot/poker.hpp:5,
                 from godot/poker.cpp:1:
godot-cpp/include/godot_cpp/core/method_bind.hpp: In instantiation of 'GDExtensionVariantType godot::MethodBindTRS<R, P>::gen_argument_type(int) const [with R = SingleHandRankingEvaluationResult; P = {godot::PackedStringArray}]':
godot-cpp/include/godot_cpp/core/method_bind.hpp:674:33:   required from here
godot-cpp/include/godot_cpp/core/method_bind.hpp:678:71: error: incomplete type 'godot::GetTypeInfo<SingleHandRankingEvaluationResult, void>' used in nested name specifier
  678 |                         return GDExtensionVariantType(GetTypeInfo<R>::VARIANT_TYPE);
      |                                                                       ^~~~~~~~~~~~
godot-cpp/include/godot_cpp/core/method_bind.hpp: In instantiation of 'godot::PropertyInfo godot::MethodBindTRS<R, P>::gen_argument_type_info(int) const [with R = SingleHandRankingEvaluationResult; P = {godot::PackedStringArray}]':
godot-cpp/include/godot_cpp/core/method_bind.hpp:682:23:   required from here
godot-cpp/include/godot_cpp/core/method_bind.hpp:688:62: error: incomplete type 'godot::GetTypeInfo<SingleHandRankingEvaluationResult, void>' used in nested name specifier
  688 |                         return GetTypeInfo<R>::get_class_info();
      |                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
godot-cpp/include/godot_cpp/core/method_bind.hpp: In instantiation of 'GDExtensionClassMethodArgumentMetadata godot::MethodBindTRS<R, P>::get_argument_metadata(int) const [with R = SingleHandRankingEvaluationResult; P = {godot::PackedStringArray}]':
godot-cpp/include/godot_cpp/core/method_bind.hpp:697:49:   required from here
godot-cpp/include/godot_cpp/core/method_bind.hpp:701:48: error: incomplete type 'godot::GetTypeInfo<SingleHandRankingEvaluationResult, void>' used in nested name specifier
  701 |                         return GetTypeInfo<R>::METADATA;
      |                                                ^~~~~~~~
In file included from godot-cpp/include/godot_cpp/core/method_bind.hpp:34:
godot-cpp/include/godot_cpp/core/binder_common.hpp: In instantiation of 'void godot::call_with_variant_args_static_ret(R (*)(P ...), const Variant**, Variant&, GDExtensionCallError&, IndexSequence<Is ...>) [with R = SingleHandRankingEvaluationResult; P = {PackedStringArray}; long unsigned int ...Is = {0}]':
godot-cpp/include/godot_cpp/core/binder_common.hpp:584:35:   required from 'void godot::call_with_variant_args_static_ret_dv(R (*)(P ...), const void* const*, int, Variant&, GDExtensionCallError&, const std::vector<Variant>&) [with R = SingleHandRankingEvaluationResult; P = {PackedStringArray}; GDExtensionConstVariantPtr = const void*]'
godot-cpp/include/godot_cpp/core/method_bind.hpp:707:39:   required from 'godot::Variant godot::MethodBindTRS<R, P>::call(GDExtensionClassInstancePtr, const void* const*, GDExtensionInt, GDExtensionCallError&) const [with R = SingleHandRankingEvaluationResult; P = {godot::PackedStringArray}; GDExtensionClassInstancePtr = void*; GDExtensionConstVariantPtr = const void*; GDExtensionInt = long int]'
godot-cpp/include/godot_cpp/core/method_bind.hpp:705:18:   required from here
godot-cpp/include/godot_cpp/core/binder_common.hpp:546:15: error: no match for 'operator=' (operand types are 'godot::Variant' and 'SingleHandRankingEvaluationResult')
  546 |         r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
      |         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:36,
                 from godot-cpp/include/godot_cpp/core/method_ptrcall.hpp:36,
                 from godot-cpp/include/godot_cpp/core/binder_common.hpp:36:
godot-cpp/include/godot_cpp/variant/variant.hpp:252:18: note: candidate: 'godot::Variant& godot::Variant::operator=(const godot::Variant&)'
  252 |         Variant &operator=(const Variant &other);
      |                  ^~~~~~~~
godot-cpp/include/godot_cpp/variant/variant.hpp:252:43: note:   no known conversion for argument 1 from 'SingleHandRankingEvaluationResult' to 'const godot::Variant&'
  252 |         Variant &operator=(const Variant &other);
      |                            ~~~~~~~~~~~~~~~^~~~~
godot-cpp/include/godot_cpp/variant/variant.hpp:253:18: note: candidate: 'godot::Variant& godot::Variant::operator=(godot::Variant&&)'
  253 |         Variant &operator=(Variant &&other);
      |                  ^~~~~~~~
godot-cpp/include/godot_cpp/variant/variant.hpp:253:38: note:   no known conversion for argument 1 from 'SingleHandRankingEvaluationResult' to 'godot::Variant&&'
  253 |         Variant &operator=(Variant &&other);
      |                            ~~~~~~~~~~^~~~~
godot-cpp/include/godot_cpp/core/binder_common.hpp: In instantiation of 'void godot::call_with_ptr_args_static_method_ret_helper(R (*)(P ...), const void* const*, void*, IndexSequence<Is ...>) [with R = SingleHandRankingEvaluationResult; P = {PackedStringArray}; long unsigned int ...Is = {0}; GDExtensionConstTypePtr = const void*]':
godot-cpp/include/godot_cpp/core/binder_common.hpp:594:54:   required from 'void godot::call_with_ptr_args_static_method_ret(R (*)(P ...), const void* const*, void*) [with R = SingleHandRankingEvaluationResult; P = {PackedStringArray}; GDExtensionConstTypePtr = const void*]'
godot-cpp/include/godot_cpp/core/method_bind.hpp:713:39:   required from 'void godot::MethodBindTRS<R, P>::ptrcall(GDExtensionClassInstancePtr, const void* const*, GDExtensionTypePtr) const [with R = SingleHandRankingEvaluationResult; P = {godot::PackedStringArray}; GDExtensionClassInstancePtr = void*; GDExtensionConstTypePtr = const void*; GDExtensionTypePtr = void*]'
godot-cpp/include/godot_cpp/core/method_bind.hpp:711:15:   required from here
godot-cpp/include/godot_cpp/core/binder_common.hpp:589:28: error: 'encode' is not a member of 'godot::PtrToArg<SingleHandRankingEvaluationResult>'
  589 |         PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
      |         ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scons: *** [godot/poker.os] Error 1
scons: building terminated because of errors.

If I'm reading this correctly, the error is that my custom type SingleHandRankingEvaluationResult is an incomplete type because it is incompatible with godot::Variant.

I've searched the web looking for other Godot extensions that use GDExtension for clues, but none so far has had the needs my extension has, and I've seen no extension implementing encode or the other operators like operator=.

The documentation is lacking in this regard, if someone else has experienced this problem and has solved, your input would be much appreciated.

Fireproof answered 3/11, 2023 at 17:20 Comment(0)
A
0

Fireproof Construct a Variant from Object when needed.

Alleman answered 3/11, 2023 at 20:1 Comment(0)
F
0

Alleman can you illustrate how?

Fireproof answered 4/11, 2023 at 7:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.