> Would that actually work? it does not feel good to allocate a string to
> convert it to a cstring. What's the best way to do here?
Allocating a string and callind `cstring` does work for passing string.
What I usually do is make a lightweight wrapper on proc like these so I can
pass string directly :
Here is a typical example, just ask if something is not clear :
// example.c
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#define MAX_LEN 255
void dummy(char bufMsg[MAX_LEN]) {
strcpy(bufMsg, "azerty"); // This is just a dummy example
printf("%s \n", bufMsg);
}
// Sometimes you also have
void dummySize(char * bufMsg, size_t bufSize) {
if(bufSize < 10) {
printf("C program says: Error buffer too small\n");
return;
}
strcpy(bufMsg, "0123456789"); // In reality, check that you don't write
over bufSize
printf("%s \n", bufMsg);
}
Run
# example.nim
import strutils
{.compile: "example.c".}
const MAX_LEN = 255
proc c_dummy(bufMsg: cstring) {.importc: "dummy", cdecl.}
proc c_dummySize(bufMsg: cstring, bufSize: csize_t) {.importc: "dummySize",
cdecl.}
proc dummy(): string =
result = newString(MAX_LEN);
c_dummy(result.cstring)
result = $(result.cstring)
proc dummySize(bufSize: int): string =
result = newString(bufSize);
c_dummySize(result.cstring, result.len.csize_t)
# Why do I do that ?
# Because newString create a buffer of size bufSize full of zeros
# The C function will not (usually write) in all the memory.
# result represent as an array now contains : ['0', '1', '2', '3', '4',
'5,', '6', '7', '8', '9',char(0), char(0), char(0), ..., char(0)]
# Which is not typically what you want. So converting to cstring and back
will strip result of '0' char (you can also use strip from std/strutils)
result = $(result.cstring)
doAssert dummy() == "azerty"
doAssert dummySize(12) == "0123456789"
let res = dummySize(5) # Here you see the printf : your buffer is too small
doAssert res.isEmptyOrWhitespace() # res is empty because the C didn't
write any data inside : it's full of char(0)
Run
I personnaly wouldn't use `array[LEN, char]` to represent `char *` because it
would be harder to use from Nim side: dealing manually with null termination or
even simply writing a string in your `array[char]` just wouldn't be practical.
So unless your `char*` is actually a buffer that does not need to be null
terminated (in which case you really should use `uint8_t*`), I don't recommend
using array.