Pyrollo wrote: ↑Thu Aug 20, 2020 08:52
If you want to have the string representation of your u64 (ie "123456789" for example), you should use sprintf function to do that.
I just looked up the sprintf(), and it seems to write to a buffer of some sort. That sounds like outputting to the console or something, unless I'm misunderstanding. Would there be a way to use a variable as the buffer or something?
Pyrollo wrote: ↑Thu Aug 20, 2020 08:52
I don't really catch the idea. Your function would be useful only to convert alphabetic seeds to number seeds represented as a string. Is this what you need ?
Yes. That's exactly what I need.
Pyrollo wrote: ↑Thu Aug 20, 2020 08:52
You could also push the result as integer on Lua stack, but unfortunately the Lua number representation can't handle such precision (64 bits, integer), it looses less significant digits.
That's exactly why I cast the u64 into a string first. Lua's string length is more than capable of handling the seed in its full length if it's represented in string form.
Pyrollo wrote: ↑Thu Aug 20, 2020 08:52
numeric_seed is a u64 and you cast it to a char pointer (so pointing to kind of random memory area).
Hmm. I don't think I fully understood what you meant by that at first. I think I get it now though. When I cast the u64 to a char*, it's not generating a new char* that holds the string representation of the integer. Instead, it's using the value of the u64 as the address of a pointer. Is that correct? It certainly would explain the segfault. Until the pointer gets used, no error occurs, but when it does, which happens within the lua_pushstring() function when I pass that pointer, this memory address which was never allocated (... I can't remember the right term ... it's the opposite of "freed" though ...) gets accessed, at which point a segfault would occur.
Thank you very much for the insight, Pyrollo! I'll see what I can figure out about converting integers into strings, starting with researching the sprintf() function and buffers.
EDIT:
Alright, I think I have it figured out. Thanks again, Pyrollo! My final function ended up as follows, in case anyone is curious now or in the future. It's always a bit annoying when I see a topic like this about a problem that was solved and the final solution is still nowhere to be seen.
Code: Select all
int ModApiServer::l_read_seed(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char * seed = luaL_checkstring(L, 1);
char* buffer = new char[20];
sprintf(buffer, "%lu", read_seed(seed));
lua_pushstring(L, buffer);
return 1;
}
I'm not sure if there's a way to dynamically figure out how long the character buffer should be without putting in a bunch of mathematical logic with twenty separate cases, one for each appropriate length. Or I guess a loop could be used to repeatedly divide the number by ten until the value is less than ten, as a way to count the digits. In any case, I have a notes file about what I've learned about Minetest and need to remember, and it tells me the maximum seed is 18446744073709551615, which is 20 digits long, so a buffer of 20 should always be long enough, and sometimes too long. My calculator isn't precise enough to check this value (which should be 2^64-1), but the value should be correct. Experimentation has shown that having the buffer be too long doesn't seem to cause noticeable problems for now. It's probably less memory-efficient, but that's fine for my project. This isn't code to be put into the official Minetest engine, so making it as clean and efficient as possible isn't a priority.