How wrapp strcpy of libc which ccall, this does not work for me
to=Ref{Cstring}()
ccall(:strcpy, Ptr{UInt8}, (Ref{Cstring}, Ptr{UInt8}), to, "Hello")
unsafe_string(to)
How wrapp strcpy of libc which ccall, this does not work for me
to=Ref{Cstring}()
ccall(:strcpy, Ptr{UInt8}, (Ref{Cstring}, Ptr{UInt8}), to, "Hello")
unsafe_string(to)
The issue with your example is that you are not allocating any memory for the destination pointer. Ref{Cstring}()
is an empty string. Technically what you want to do is possible in Julia, but it is risky even for expert C developers. See pointer
or Libc.malloc
depending on whether the memory needs to be owned by Julia. Please carefully read the “Calling C” section of the manual, especially this and the following section:
https://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#Memory-Ownership-1
Maybe you could explain what you’re trying to achieve? There’s probably an easier way of doing it.
Just to learn, this works for me
function test(s)
to = Ptr{UInt8}(Libc.malloc(length(s)*sizeof(Char)))
ccall(:strcpy, Ptr{UInt8}, (Ptr{UInt8}, Ptr{UInt8}), to, s)
str = unsafe_string(to)
Libc.free(to)
str
end
julia> test("Hello World!")
Thank you
Why would you want to do this?
It’s not at all I’m just trying to learn how to use ccall, with examples of libc
Sorry for my English, I’m Spanish
Is there any downsides to using an array to allocate memory instead of malloc ?
to = Array{UInt8}(sizeof(s))
It’s unclear what you’re trying to do, but this code is wrong; I’ve added comments inline to indicate possible corrections:
function test(s)
to = Ptr{UInt8}(Libc.malloc(length(s)*sizeof(Char)))
# should allocate `sizeof(s)` bytes
ccall(:strcpy, Ptr{UInt8}, (Ptr{UInt8}, Ptr{UInt8}), to, s)
# the use of strcpy in C should be avoided, use memmove instea
# if you must deal with a poorly-designed C-api that uses `char*` without a size/length argument,
# be sure to mark the types as `Cstring` in the `ccall` so they are null-terminated by Julia
str = unsafe_string(to)
# could just replace this function with `return s` :P
Libc.free(to)
# its often recommended to wrap the usage in try/finally
# so that error don't leak memory (or use Array allocation as suggested by jonathanBieler)
return str
end