buffer it, aww yeah that's real nice and good

Samuel Venable

Time Killer
I don't know what the heck that is, but I buffer it anyway.

tl;dr how to use buffer functions with GM extensions?

C++ func be liek:
double buffer_me_nice_and_good(char *** buffer, int *size)

How to buffs?

I want to get to get the buffer copied to char pointer and the size integer pointer as well, it's a vector of char *.

Is too how buffs?

If you can read past the weirdness, this is a real and serious question I just am too lazy to explain more intelligently.
Thank
 

rwkay

YoYo Games Staff
YYG Staff
OK for an extension then all strings are passed as char*,so if you declare the extension in GM as taking a string then a pointer is passed instead

if you take a look at https://github.com/YoYoGames/GameMakerStudio_ExtensionExample then you will see that in the https://github.com/YoYoGames/GameMakerStudio_ExtensionExample/blob/master/ExampleExtension.cpp file the function MyExtension_BufferPointer declaration is the correct way to do it, on the GM side the first param would be a string.

C++:
EXPORTED_FN  char*  MyExtension_BufferPointer( void* _pBuffer, double _size)
{
    if( !g_Initialised ) return NULL;

    unsigned char* pBuffer = (unsigned char*)_pBuffer;
    int i,total = 0;
    for(i=0;i<_size;i++){
        total+=pBuffer[i];                    // buffer read example
        pBuffer[i] = (unsigned char)i;        // buffer write example
    }


    char s[1024];
    snprintf(&s[0], 1023, "Total = %d", total);
    char* pString = strdup(s);
    return pString;
}
the _pBuffer parameter is declared as a void pointer but is then cast to be an unsigned char*

In the GML code use buffer_get_address() to get the base of the buffer and pass that pointer to the C++

Any probs let me know

Russell
 

Samuel Venable

Time Killer
OK for an extension then all strings are passed as char*,so if you declare the extension in GM as taking a string then a pointer is passed instead

if you take a look at https://github.com/YoYoGames/GameMakerStudio_ExtensionExample then you will see that in the https://github.com/YoYoGames/GameMakerStudio_ExtensionExample/blob/master/ExampleExtension.cpp file the function MyExtension_BufferPointer declaration is the correct way to do it, on the GM side the first param would be a string.

C++:
EXPORTED_FN  char*  MyExtension_BufferPointer( void* _pBuffer, double _size)
{
    if( !g_Initialised ) return NULL;

    unsigned char* pBuffer = (unsigned char*)_pBuffer;
    int i,total = 0;
    for(i=0;i<_size;i++){
        total+=pBuffer[i];                    // buffer read example
        pBuffer[i] = (unsigned char)i;        // buffer write example
    }


    char s[1024];
    snprintf(&s[0], 1023, "Total = %d", total);
    char* pString = strdup(s);
    return pString;
}
the _pBuffer parameter is declared as a void pointer but is then cast to be an unsigned char*

In the GML code use buffer_get_address() to get the base of the buffer and pass that pointer to the C++

Any probs let me know

Russell
I'm not 100% sure if I understand correctly, but I'll try your example and throw together a small project that calls that and see how it responds to it. (I think?) Seems like I'm supposed to pass buffer_get_size(buffer) to the second argument, and of course because of the strdup I need to free the buffer from memory on the gml as well. Let's hope I know what I'm doing enough my computer doesn't esplode.

Will ask more questions here if needed. Thank you!!!
 

rwkay

YoYo Games Staff
YYG Staff
If you are looking to pass back any more than a string from the C++ then you would be better to use the buffer to pass back any other types of data.

Russell
 

JeffJ

Member
OK for an extension then all strings are passed as char*,so if you declare the extension in GM as taking a string then a pointer is passed instead

if you take a look at https://github.com/YoYoGames/GameMakerStudio_ExtensionExample then you will see that in the https://github.com/YoYoGames/GameMakerStudio_ExtensionExample/blob/master/ExampleExtension.cpp file the function MyExtension_BufferPointer declaration is the correct way to do it, on the GM side the first param would be a string.

the _pBuffer parameter is declared as a void pointer but is then cast to be an unsigned char*

In the GML code use buffer_get_address() to get the base of the buffer and pass that pointer to the C++
Slightly off topic, but I feel like this type of stuff should be officially documented - from time to time I stumble upon what seems to be internal stuff that is good to know but not documented anywhere, and this is a good example of this. Question is, where in the docs would be fitting?
 

Samuel Venable

Time Killer
Slightly off topic, but I feel like this type of stuff should be officially documented - from time to time I stumble upon what seems to be internal stuff that is good to know but not documented anywhere, and this is a good example of this. Question is, where in the docs would be fitting?
I could give matharoo a little help with extension-related documentation, but the only stuff that isn't already covered I don't actually know how to do either. I'm still a little confused by what Russell told me to do, but i often have that problem in other communities when people explain stuff to me c++-related anyway it usually takes for me to do a bit of debugging before i have one of those "oh, gotcha!" moments. Perhaps I could help him with it after I figure it out myself. We'll see what happens. I've been working on other stuff alongside this.
 
Top