Hi, how do I convert a std::vector<std::string> to a Variant for returning from a c++ GDExtension?

Variant GDSerialPort::tester()
{
	UtilityFunctions::print("testerrrrrr");
	
	Variant v;
	
	std::vector<std::string> l = get_available_ports();
    
    //cout << "..." << endl;
    
    if(l.size() == 0){
    	//cout << "No devices found" << endl;
    	UtilityFunctions::print("No devices found");
    	
    	l.push("No devices found");
    }
    /*
    else
    {
		std::vector<std::string>::iterator it = l.begin();
		while (it != l.end()) {
		    //cout << *it << endl;
		    UtilityFunctions::print(std::string(*it).c_str());
		    it++;
		}
    }
    */
	
	v = l;		//	*** THIS BIT	***
	
	//Variant v = 3;
	//Variant v = "helllllllllo";
	return v;
}

Whilst we are at it,
Here is how to read a passed Variant of an array of strings?

Variant GDSerialPort::alice(Variant v2)
{
	UtilityFunctions::print("Aliced");
	UtilityFunctions::print(v2);
	UtilityFunctions::print(v2.get(1));
	
	//Variant v;
	//Variant v = 3;
	Variant v = "Alice";
	return v;
}

from

func _ready():
	var y = alice(["you", "Whaaaaat!"])

Thankyou

  • totoro replied to this.
  • I have exactly zero experience with GDExtensions but I peeked into variant.cpp. It has a constructor that takes Array const &. So maybe simply try returning:

    return *a; // or return Variant(*a)

    totoro

    I appear to have got this far with a variant / array

    Variant GDSerialPort::tester()
    {
    	UtilityFunctions::print("testerrrrrr");
    	
    	Variant v;
    	
    	Array *a = memnew(Array);
    	a->push_back("One");
    	a->push_back("Two");
    	
    	std::vector<std::string> l = get_available_ports();
        
        if(l.size() == 0){
        	a->push_back("No devices found");
        }
        else
        {
    		std::vector<std::string>::iterator it = l.begin();
    		while (it != l.end()) {
    		    UtilityFunctions::print(std::string(*it).c_str());
    		    a->push_back(std::string(*it).c_str());
    		    it++;
    		}
        }
    	
    	//v = l;		//	*** THIS BIT	***
    	v = a;
    	
    	//return v;
    	return a;
    }

    but it prints "true" on return in gdscript... any ideas?

      I have exactly zero experience with GDExtensions but I peeked into variant.cpp. It has a constructor that takes Array const &. So maybe simply try returning:

      return *a; // or return Variant(*a)

        xyz

        Oops, embarrassed emoji, I must have been really mashed... Many thanks, doh!

        • xyz replied to this.

          totoro Oh, so it works then 🙂
          Yeah, you were returning a naked pointer that probably got casted into boolean.

          Btw I hope that memnew() is not just a malloc() wrapper. If it is - you're creating a memory leak there.

            5 days later

            xyz
            Why yes it is! I read somewhere I was supposed to use it, also my programming is self taught so any pointers happily received...

            I also got stuck passing over a string variant... trying c_str, stringify, etc

            Variant GDSerialPort::serial_send(Variant v){
            	std::string s = std::string(v);

            😃

            • xyz replied to this.

              totoro
              Guessing again from looking at the source code:

              std::string s = v.stringify(0);

              or

              std::string s = v.stringify(0).get_data();

              Variant::stringify() returns Godot's String type which has overloaded operator=() that returns char32_t*. I think that should be enough to satisfy one of std::string's constructors.

              EDIT:
              Hm, the above won't work. Looks like Godot's strings are 32 bit unicode. You can construct std::u32string though and then convert it to std::string