Hello. I am doing a plugin for winsock because I could not get the standard TCP Peer class to connect.

I tried many different things by looking at the example in the godot source code and right now I have something like this:

void WinSocket::set_message_buffer(godot::Ref<godot::PoolByteArray> &messageBuffer)
{
	this->messageBuffer = messageBuffer.ptr();
	//this->messageBuffer = messageBuffer;
}

But I am getting some cryptic errors when compiling:

C:\Projects\godot-cpp\include\core\Godot.hpp(131): error C2440: 'return': cannot convert from 'godot::Variant' to 'T' with [ T=godot::Ref<godot::PoolByteArray> & ] C:\Projects\godot-cpp\include\core\Godot.hpp(130): note: while compiling class template member function 'T godot::_ArgCast<T>::_arg_cast(godot::Variant)' with [ T=godot::Ref<godot::PoolByteArray> & ] C:\Projects\godot-cpp\include\core\Godot.hpp(263): note: see reference to function template instantiation 'T godot::_ArgCast<T>::_arg_cast(godot::Variant)' being compiled with [ T=godot::Ref<godot::PoolByteArray> & ] C:\Projects\godot-cpp\include\core\Godot.hpp(262): note: see reference to class template instantiation 'godot::_ArgCast<godot::Ref<godot::PoolByteArray> &>' being compiled

The code for writing to the PoolByte array looks something like this (the print(c) successfully prints the right character to the output:

	godot::PoolByteArray::Write writeObject = messageBuffer->write();
	uint8_t* ptr = writeObject.ptr();

	byte* tmpBuffer = (byte*) malloc(messageSize);
	blocking_receive(tmpBuffer, messageSize);
	for (int i = 0; i < messageSize; i++) {
		byte c = tmpBuffer[i];
		godot::Godot::print(c);
		*(ptr+i) = c;
	}
	::free(tmpBuffer);

My gdscript code looks like this, but nothing gets printed when calling get_string_from_ascii()

extends Node

export var win_socket_script: NodePath
var win_socket
var dataBuffer: PoolByteArray

func _ready():
    dataBuffer.resize(16384)
    win_socket = get_node(win_socket_script)
    win_socket.connect_to_host("localhost", 2000)
    win_socket.set_message_header_size(2)
    win_socket.set_message_buffer(dataBuffer)

    print("Waiting for message...")
    win_socket.blocking_receive_message()
    print("Received message:")
    print(dataBuffer.get_string_from_ascii())

The reason I tried to pass by reference now, using Ref, is without it the code compiles but any changes I do to the PoolByteArray from gdnative does not seems to reflect in gdscript.

For anyone having the same problem, I managed to get it working myself by using a StreamPeerBuffer instead, which properly inherits the Reference class:

void WinSocket::set_message_buffer(godot::Ref<godot::StreamPeerBuffer> messageBuffer)
{
	this->messageBuffer = messageBuffer;
}

The code is still a bit dodgy since I allocate a new byte array for every message received, I rather just start writing data to the StreamPeerBuffer.data_array directly in the socket call. This code works but it is not very pretty:

	godot::PoolByteArray* poolByteArray = &messageBuffer.ptr()->get_data_array();
	byte* tmpBuffer = (byte*) malloc(messageSize);
	blocking_receive(tmpBuffer, messageSize);
	for (int i = 0; i < messageSize; i++) {
		byte c = tmpBuffer[i];
		poolByteArray->set(i, c);
		godot::Godot::print(c);
	}
	::free(tmpBuffer);

And my gdscript now looks like this:

export var win_socket_script: NodePath
var win_socket
var dataBuffer: StreamPeerBuffer

func _ready():
    dataBuffer = StreamPeerBuffer.new()
    dataBuffer.resize(16384)
    win_socket = get_node(win_socket_script)
    win_socket.connect_to_host("localhost", 2000)
    win_socket.set_message_header_size(2)
    win_socket.set_message_buffer(dataBuffer)

    print("Waiting for message...")
    win_socket.blocking_receive_message()
    print("Received message:")
    print(dataBuffer.get_string(11))
a year later