#How do you create a sentinel pointer to a stack buffer?

1 messages · Page 1 of 1 (latest)

rare fiber
#

I'm trying to call the windows API GetWindowTextA. It outputs to a LPSTR which is a [*:0]u8. When I reference my buffer locally I get the error expected type '[*:0]u8', found '[]u8'. I'm sure this is a easy one to fix, but I'm still new at Zig and low level languages so I'm struggling to get this right. Here is the relevant pieces of code:

pub extern "user32" fn GetWindowTextA(
    hWnd: HWND,
    lptString: LPSTR,
    nMaxCount: INT,
) callconv(.winapi) INT;
var windowHandle = GetTopWindow(null);
var windowText: [2048]u8 = undefined;

while (windowHandle) |handle| {
    if (IsWindowVisible(handle) > 0) {
        var titleLength = GetWindowTextA(handle, &windowText, windowText.len);
        titleLength = if (titleLength > windowText.len) windowText.len else titleLength;
        const len = std.math.cast(usize, titleLength) orelse @panic("Could not cast c_int to usize.");
        std.debug.print("{s}\n", .{windowText[0..len]});
    }
    windowHandle = GetWindow(handle, 2);
}
    
uncut sun
#

I think that signature might be wrong, as [*]u8 might be what is wanted, given that it tells you how long the returned string is(?)

magic stirrup
#

it seems a bit weird for a function to require a null-terminator on a pointer, if that argument is written to (not read from)

rare fiber
magic stirrup
#

like @uncut sun said, I also think the signature is wrong, and the function is supposed to accept a [*]u8

uncut sun
#

The string that's written appears to include a null terminator, so the buffer will end up with a null terminated string, but you are also given the length not including the null byte in the return value, so it doesn't matter

#

LPSTR means [*:0]const u8 (cstring) indeed, but you'd translate that to Zig as [*]u8, given how the function works, and that there's no need to have a null to the function - only a buffer.

magic stirrup
#

the docs say:

The buffer that will receive the text. If the string is as long or longer than the buffer, the string is truncated and terminated with a null character.
the parameter is marked [out], I think it's safe to say the null terminator is unneeded, and will be added by the function when it runs

uncut sun
#

Indeed

rare fiber
#

Okay thanks guys. I've updated the signature of GetWindowTextA to this:

pub extern "user32" fn GetWindowTextA(
    hWnd: HWND,
    lptString: [*]u8,
    nMaxCount: INT,
) callconv(.winapi) INT;

And now it's working 🎉