#What is the proper way to pass these kind data to c function?

1 messages · Page 1 of 1 (latest)

outer sedge
#

I have a function imported from c, the signature is like this:

pub extern fn foo(input: some_ptr, output: [*c][*c]u8) void;

Now let's preallocate a buffer called buffer to store the output.
And I have to mod the buffer ptr like this to fit into the foo function:

const buffer = allocator.alloc(u8, capacity) catch unreachable;
defer allocator.free(buffer);
var buffer_ptr: [1][*c]u8 = .{@ptrCast(buffer)}; // I have to construct a 2D array
c.foo(&input, &buffer_ptr);

Is this the correct way? I can get the correct answer from this code, but I guess there are potential issues in it.


By the way, in rust I managed to pass the buffer like this:

let mut buffer = vec![0u8; 1024];
c.foo(&mut input, &mut buffer.as_mut_ptr());

No two dimensional array is needed in rust.

desert anvil
#
const buffer = allocator.alloc(u8, capacity) catch unreachable; // please do actual error handling lol
defer allocator.free(buffer);
c.foo(&input, &.{buffer.ptr});

should work on 0.12, previous versions youll need to do something more like &[_][*]u8

#

if you find yourself using [*c] in your code it means youre wrong in some way, its sole reason for existence is use in translate-c

outer sedge
#

It says: error: type '[*c]u8' does not support array initialization syntax

desert anvil
#

oh wait yeah im wrong, that wouldnt work anyway because constness

outer sedge
#

"if you find yourself using [*c] in your code it means youre wrong in some way, its sole reason for existence is use in translate-c" very useful info, I'll remember this

outer sedge
desert anvil
#

ok var buffer_ptr = [_]?[*]u8{buffer.ptr}; is what you want

desert anvil
outer sedge
#

I find out @ptrCast(&buffer) can do the trick

outer sedge
desert anvil
outer quarry
#

this should work w/ uncle's buffer

    var tmp = [_][*]u8{buffer.ptr};
    foo(&input, @ptrCast(&tmp));
desert anvil
outer sedge
outer quarry
#

ah thats why you made it optional

#

i agree its better without the ptr cast since that can hide issues. it compiles like this

var tmp = [_]?[*]u8{buffer.ptr};
#

(and no ptr cast)

outer sedge
desert anvil
#

it means the elements are optional pointers, they can be null

outer sedge
#

Oh, i think i get it.

desert anvil
#

its needed since [*c] is implicitly nullable so doing this allows the code to work without ptrCast

outer sedge
#

Thank you guys.

desert anvil
#

also
your original message pointed out that rust didnt need a 2d array which id argue is a bad thing. if the C lib tried to modify the array the value would be lost in that rust code, in zig it doesnt allow you to do something like that

#

mutable temporary values like that are sketchy imo

outer sedge
#
    // why this works
    var buffer_ptr: [1][*c]u8 = .{buffer.ptr};
    // but this will cause: error: expected type '[*c][*c]u8', found '*[1][*]u8'
    var buffer_ptr = [1][*]u8{buffer.ptr};
outer sedge
outer quarry
#

should be

var buffer_ptr = [1]?[*]u8{buffer.ptr};