How to convert a MemoryBlock cleanly to a Ptr?

I am building a shader in OpenGL to work with code at runtime in the GPU. When I convert a MemoryBlock to a pointer, data is added to the pointer. When I attempt to pass the pointer to glShaderSource, the program crashes since the added data is not part of the original code. How do I convert a MemoryBlock (with its data) cleanly to a Ptr?
Here is code in a Xojo pushbutton to demonstrate the added data:

The MemoryBlock has the correct size data and it is as follows:
CorrectMBData

When I convert the MemoryBlock to a Pointer then the data is changed to:
IncorrectPtrData

It appears that introspection data from Xojo has been added. When the glShaderSource attemps to compile the original C code, then it has errors since the length of data in the pointer has changed,

Here is the glShaderSource information, and the third parameter is an array of pointers, which complicates the conversion.

How do I convert the MemoryBlock cleanly to a pointer so that I can have pointers to pass to glShaderSource?

Thanks :slight_smile:

the data is not added. You just see what is behind the memory block in memory, since a Ptr has no size field.

2 Likes

Yes, you are correct @Christian_Schmitz. Placing a Ptr in the glShaderSource and adding the correct length causes a silent crash.

Is there a way to have an array of pointers to strings for the third parameter?

My working code in C/C++ accepts the following code and works:
const std::string& source //source is the sFragmentShader string
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);

Thanks for your experienced help :slight_smile:

Are you passing the ptr ByRef? That would work with a count of 1. To pass multiples, you would store the ptr’s in a memoryblock and pass that byref.

1 Like

Thanks for the suggestion @Tim_Hare,

I just tried with ByRef and a count of 1, unfortunately, it silently crashed. The C/C++ code gets a pointer for each character, I’ll put something together to create an array of pointers for each character in the string with and see how it works.

Thanks!

I think it should work like this, for an array of code strings s():

Var Count As Integer = s.Count
Var PtrMB As New MemoryBlock (Count * 8 + 1) // MB for the ptrs
Var LengthMB As New MemoryBlock (Count * 4 + 1) // considering GLInt is an Int32. Didn’t check.
// And considering both arrays follow usual C-Array structure with a trailing 0 Byte.
Count = Count - 1
For q As Integer = 0 to Count
   Var StringMB As MemoryBlock = s(q)
   Var p As Ptr = StringMB
   PtrMB.Ptr(q*8) = p
   LengthMB.Int32Value(q*4) = StringMB.Size
Next q

And then pass PtrMB and LengthMB to the method where both parameters are declared as Ptr.

1 Like

@Ulrich_Bogun,

Fantastic, it worked well! Thank you for your help.

1 Like