• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Windows Whats the deal with the ptr() function?

I have a slight feeling that this function doesn't do the awesome things I wanted it too.

If I'm correct, it should return the memory address of a variable that I choose, but I can't seem to get it to work right. Does it not work with the VM compile, or is the function fake? If all it does is convert to hex, I'd presume naming it 'hex' would be better, not ptr.

I'm sending the returned values to a DLL, hoping I'd be able to make some really nice improvements to MAEngine. I'm doing this, but I'm not sure if it's right, since all I'm getting is hexadecimal versions of the same number, not a memory address.

This is how I'm sending.
Code:
///GML
///GMLEObjectHook();
gml_pragma("forceinline");

//Hook Coordinates
external_call(GMLEController.FUNC[0], ptr(x), ptr(y), ptr(z));
This is how I'm receiving.
Code:
///DLL / C++
GMEXPORT double ObjectHook(double* x, double* y, double* z) {
    obj = new CObject(x, y, z);
    std::cout << x << std::endl;
    std::cout << y << std::endl;
    std::cout << z << std::endl;
    return 1;
}
These are what GM is saying the memory addresses are:
00000200
00000100
00000004
I started with an X of 512, Y of 256 and a Z of 4, which is the equivalent of those in decimal.


Any ideas? Being able to manage memory in C++ could be groundbreaking for extensions.
 
I've tried them all, draw_text, show_debug_message, show_message and printing them in C++. Always shows the same values, a hexadecimal conversion.

The documentation isn't even written properly for this function, it doesn't make any sense what so ever, for either GMS1.4 or GMS2.
 
Update:
Using the YYC changes absolutely nothing, so it's not a problem with either the VM or YYC. Does this function even do what I think it does? With a name like ptr, I'd presume it does?
 

jo-thijs

Member
Update:
Using the YYC changes absolutely nothing, so it's not a problem with either the VM or YYC. Does this function even do what I think it does? With a name like ptr, I'd presume it does?
I don't think so.
ptr(n) gives you a pointer to the memory address n.
It's basically just the number n with a different type tag.
I don't think it's a bug, but the documentation about it is garbage.

If you apply ptr to an array, it will just simply return the result of ptr applied to the first number of the array.
If you apply ptr to a string, it will just simply return the null pointer.

There's nolegit way to get a pointer to some variable's value in GameMaker as far as I know.
I'm not even sure if it would make sense to have pointers to variables in GameMaker,
since you can compile your project for HTML5 targets, which produces js code, which doesn't support pointers.

You can try to figure out the pointer values yourself, but even if you would somehow figure it out,
it will be different on other targets, it may be different on different machines and it may be different in future updates.

What you can do however is the following.
You let the DLL create new variables of which the pointers are returned.
You can then convert them to their values using other functions of the DLL.
This wouldn't be very convenient though.
 
You can try to figure out the pointer values yourself, but even if you would somehow figure it out,
it will be different on other targets, it may be different on different machines and it may be different in future updates.

What you can do however is the following.
You let the DLL create new variables of which the pointers are returned.
You can then convert them to their values using other functions of the DLL.
This wouldn't be very convenient though.
I’ve tried getting the pointers myself, to both functions and variables so I could use them in c++ like the old GMAPI, but the address changes when you modify and recompile, making it useless.

I’ve gone the route of creating pointers in a dll and casting them to normal doubles or a string (char*) for storage in GM, but that doesn’t let me do what i was after, which is fully wrap GM variables in C++; id be able to do threaded physics like that, and other multi core treats.

If they let us have window_device() a function to return the d3d device pointer, then I can’t see why they’d not let us have a ptr function, its optional for other platforms.

The value that ptr() returns does technically create a reference to the original variable, as when you edit the original, the ‘pointer’ value changes. But it changes the address.

If a yoyogames staff member checks this out, consider it a good idea to rename this function or make it do what it should with a name like that. Pointless having types if they don’t work properly.
 

PNelly

Member
I have a slight feeling that this function doesn't do the awesome things I wanted it too.

If I'm correct, it should return the memory address of a variable that I choose, but I can't seem to get it to work right. Does it not work with the VM compile, or is the function fake? If all it does is convert to hex, I'd presume naming it 'hex' would be better, not ptr.

I'm sending the returned values to a DLL, hoping I'd be able to make some really nice improvements to MAEngine. I'm doing this, but I'm not sure if it's right, since all I'm getting is hexadecimal versions of the same number, not a memory address.

This is how I'm sending.
Code:
///GML
///GMLEObjectHook();
gml_pragma("forceinline");

//Hook Coordinates
external_call(GMLEController.FUNC[0], ptr(x), ptr(y), ptr(z));
This is how I'm receiving.
Code:
///DLL / C++
GMEXPORT double ObjectHook(double* x, double* y, double* z) {
    obj = new CObject(x, y, z);
    std::cout << x << std::endl;
    std::cout << y << std::endl;
    std::cout << z << std::endl;
    return 1;
}
These are what GM is saying the memory addresses are:


I started with an X of 512, Y of 256 and a Z of 4, which is the equivalent of those in decimal.


Any ideas? Being able to manage memory in C++ could be groundbreaking for extensions.
If you look in the manual under "data types" you'll see an entry for pointers that has in its description: "You cannot do operations on a pointer and it is used for some very specific functions, like getting a texture or buffer address from memory for another function. For examples of functions that return a pointer you can see buffer_get_address or sprite_get_texture."

Even if you could get pointers to individual GM variables I'm not sure how much that would change? I suppose you could modify values without actually making external function calls/returns but I'm skeptical that's going to provide some kind of large performance boost.

EDIT: I reread and see your comment about taking advantage of threading externally, I suppose that would make a pretty big difference in performance.

Can you not manage your own memory within your C++ code? What's there to stop your from calling new() and delete() on your own heap space inside the DLL code? I haven't messed with writing DLL's before so I don't know. Aside from doing that I'm not sure what you mean by managing memory, it doesn't seem like a good idea to me to try and wrestle control away from GM's garbage collector.

Anyhow, if you're desperate to pass a memory location out of GM to your extension then buffer_get_address() is probably the way to go.
 

rwkay

GameMaker Staff
GameMaker Dev.
ptr() does not return a pointer to anything but it takes the number (or variable) that you give it and makes it an internal pointer type, this is used for passing around internal values between internal and external sources.

It has very little application for end users and does not do what you think (i.e DOES NOT return the address of a variable, that would be a huge security hole).

Use buffers if you want more control, then pass the buffer to the DLL through buffer_get_address()

Russell
 
If you look in the manual under "data types" you'll see an entry for pointers that has in its description: "You cannot do operations on a pointer and it is used for some very specific functions, like getting a texture or buffer address from memory for another function. For examples of functions that return a pointer you can see buffer_get_address or sprite_get_texture."

Even if you could get pointers to individual GM variables I'm not sure how much that would change? I suppose you could modify values without actually making external function calls/returns but I'm skeptical that's going to provide some kind of large performance boost.

EDIT: I reread and see your comment about taking advantage of threading externally, I suppose that would make a pretty big difference in performance.

Can you not manage your own memory within your C++ code? What's there to stop your from calling new() and delete() on your own heap space inside the DLL code? I haven't messed with writing DLL's before so I don't know. Aside from doing that I'm not sure what you mean by managing memory, it doesn't seem like a good idea to me to try and wrestle control away from GM's garbage collector.

Anyhow, if you're desperate to pass a memory location out of GM to your extension then buffer_get_address() is probably the way to go.
Yeah I read that in the manual, that to me doesn't tell me that pointers aren't actual memory pointers, but it's a mistake I made I guess.

I wouldn't of been so bothered had I not spent the last 6 months writing up documentation and ideas in a notebook (broken PC at the time) which relied on that function doing what I thought it did.

The performance boost would literally be from running the threaded codes and a bunch of faster C++ functions. I can load a 9MB 3D Model in C++ in about 21 milliseconds, but it takes about 8 seconds in GML.

I'm just going to use buffers as you say, my only problem with them is it won't be a 'instant' transfer of information, i'll have to call 'buffer_read()' a few times when i'm done writing in them.

Yeah I can manage my own memory, in fact I'll probably just make my own pointer/value functions instead of GMs, then store my variables on the C++ side where needed.

Cheers all, good to have this cleaned up.
 
Top