# How to create a Cstring from a String?

**URL:** https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566
**Category:** General Usage
**Tags:** strings, interoperability, c
**Created:** [May 9, 2023, 5:05pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566 "2023-05-09T17:05:25Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![heyx3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heyx3/32/29811_2.png) [@heyx3](https://discourse.julialang.org/u/heyx3)
#### Post date: [May 9, 2023, 5:05pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/1 "2023-05-09T17:05:25Z")

</div>

I’m trying to implement callback functions for a C library, to get and set the clipboard text. My functions look like this:

```julia
clipboard_get(::Ptr{Cvoid})::Cstring = string(clipboard())
const CLIPBOARD_FN_GET = @cfunction(clipboard_get, Cstring, (Ptr{CVoid{, ))

clipboard_set(::Ptr{Cvoid}, value::Cstring)::Cvoid = clipboard(unsafe_string(value))
const CLIPBOARD_FN_SET = @cfunction(clipboard_set, Cvoid, (Ptr{Cvoid}, Cstring))

```

I’m testing the functions with a manual C-style call:

```julia
println("Clipboard is: ", ccall(CLIPBOARD_FN_GET, Cstring, (Ptr{Cvoid}, ), Ptr{Cvoid}(C_NULL)))

```

However, I get a method error on the call:

```julia

ERROR: LoadError: MethodError: Cannot `convert` an object of type String to an object of type Cstring
Closest candidates are:
  convert(::Type{Cstring}, ::Union{Ptr{Int8}, Ptr{Nothing}, Ptr{UInt8}}) at C:\Users\manni\Documents\Dev Tools\Julia\v1.7.2\share\julia\base\c.jl:167       
  convert(::Type{T}, ::T) where T at C:\Users\manni\Documents\Dev Tools\Julia\v1.7.2\share\julia\base\essentials.jl:218

```

So what is the correct way to create a `Cstring` from a `String`?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [May 9, 2023, 6:00pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/2 "2023-05-09T18:00:33Z")

</div>

> [@heyx3](#):
>
> `clipboard_get(::Ptr{Cvoid})::Cstring = string(clipboard())`

How do you want to manage the memory for this? If Julia allocates a `String` object and returns a pointer to the data to C (which is possible via `unsafe_convert`), then the C code could crash if Julia garbage-collects the `String` before the C pointer is used (hence the “unsafe”). If you are okay with this — if you know for certain that the Julia string will not be garbage-collected before you use it (e.g. because you hold onto a reference to it), then you can call `Base.unsafe_convert(Cstring, s)` on `s::String`.

If C expects a `malloc`-ed string that **C** will take responsibility to `free`, then you’ll need to explicitly call `malloc` and copy the data yourself. e.g.

```julia
function malloc_cstring(s::String)
    n = sizeof(s)+1 # size in bytes + NUL terminator
    return GC.@preserve s @ccall memcpy(Libc.malloc(n)::Cstring,
                                        s::Cstring, n::Csize_t)::Cstring
end

```

Conversely, when you declare an _argument_ of a `ccall` as a `Cstring` (as is done in the call to `memcpy` here), then Julia can simply pass a pointer to the string data (assuming the data only needs to stick around for the duration of the `ccall`), first checking that the string contains no `NUL` bytes (as otherwise NUL-termination will not work; internally, Julia `String` data is already NUL-terminated so that it can be passed to C functions without copying).

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [May 9, 2023, 6:49pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/3 "2023-05-09T18:49:30Z")

</div>

Worth noting that Julia has a built-in clipboard function: [julia/clipboard.jl at master · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/master/stdlib/InteractiveUtils/src/clipboard.jl)

---

<div class="post-metadata">

### Author: ![heyx3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heyx3/32/29811_2.png) [@heyx3](https://discourse.julialang.org/u/heyx3)
#### Post date: [May 9, 2023, 6:54pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/4 "2023-05-09T18:54:40Z")

</div>

Thanks. The C library is not taking ownership of the string, so I guess I need to hold onto a persistent buffer.

I don’t have a lot of control over when/where the C library invokes this callback, but I do know when the library starts up and when it closes. So is it reasonable to manuallly `Libc.malloc` a buffer when starting the library, and `Libc.free` it when closing the library? Otherwise I’m not sure how to keep the memory `@preserve`-d as needed

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [May 9, 2023, 6:57pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/5 "2023-05-09T18:57:59Z")

</div>

> [@heyx3](#):
>
> I don’t have a lot of control over when/where the C library invokes this callback, but I do know when the library starts up and when it closes. So is it reasonable to manuallly `Libc.malloc` a buffer when starting the library, and `Libc.free` it when closing the library?

If you are managing the memory yourself, I wouldn’t bother with `malloc`/`free`. Just store it as a `String` in Julia, keep it somewhere in Julia so that it isn’t garbage-collected (e.g. have an global array of strings), and pass the pointer via `Base.unsafe_convert(Cstring, mystring)`. When you are done with the library you can remove the string(s) from your global array to allow them to be garbage-collected.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 16, 2024, 9:45pm UTC](https://discourse.julialang.org/t/how-to-create-a-cstring-from-a-string/98566/6 "2024-09-16T21:45:35Z")

</div>

2 posts were split to a new topic: [Strings and static compilation](https://discourse.julialang.org/t/strings-and-static-compilation/119474)
