-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use StringBuilder for char* used as output #88
Comments
Is |
Yes, they are null-terminated strings. I apologize for the lack of precision of my words. I still have a lot to learn. I checked the code again. Basically it copies a char* into |
You can alloc a buffer large enough (either on the stack or heap) and create a
|
Perfect! Thank you. I ended up allocating a managed buffer in order to avoid using public CString(byte[] buffer)
{
fixed (byte *ptr = buffer)
{
_pointer = (nint)ptr;
}
} Would you consider adding it to the generated bindings? |
The Instead I would see possible opening up the conversation of using int getSomething(char* input, char *output) int getSomething([MarshalAs(UnmanagedType.LPStr)] string input, MarshalAs(UnmanagedType.LPStr) out string output) |
My understanding from the documentation is that the I believe that Rust's CString is similar in spirit to the CString of c2cs. Passing a pointer to a constant-size buffer looks like this: let v = vec![0; size];
let s = CString::from_vec_unchecked(v);
let ptr = s.into_raw();
let err = call_to_ffi(ptr, size);
assert_eq!(err, 0);
let s = CString::from_raw(ptr); As I see it, the Unless there is a technical reason why this may not work in general, I would stick to using the CString abstraction in the generated bindings. |
Yes, for the scope of the fixed statement. The pointer value escapes the fixed statement; this can lead to the pointer value not pointing to what you think it's pointing to if your array changes it's location in memory (which the garbage collector is allowed to do). What you are doing is okay as long you throw away the pointer value as soon as you use it (don't store it or use it later). |
You are right. I guess the right way to do it would be string get_info() {
unsafe {
fixed (byte *ptr = byte[1024]) {
var cstring = new CString(ptr);
c_get_info(cstring);
return cstring.ToString();
}
}
} which is very verbose. The Mono Project recommends using a StringBuilder as the simplest solution, since the runtime takes care of the marshaling. I do not think it is a good idea to use |
|
I'm going to close this as a solution was provided that appears to be working. |
I generated bindings for a closed-source C API, that contains many functions of the form
In the generated C# code these functions are mapped to
The problem is, the C code expects
output
to be a pointer to a buffer of a given size. This can be accomplished by marshalling a StringBuilder.Is it possible to map
char *
to StringBuilder andchar*
to CString? What other solution do you propose?The text was updated successfully, but these errors were encountered: