# Pass structure containing String to C code

**URL:** <https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667>\
**Category:** New to Julia\
**Tags:** ccall\
**Created:** [January 24, 2017, 8:36pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667 "2017-01-24T20:36:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [January 24, 2017, 8:36pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/1 "2017-01-24T20:36:59Z")

</div>

pass structure containing string to C code

```julia
type simcase
    a::Int32
    b::Int32
    c::Cstring
end

n = 2
m = 3
x = randn(n,m)
s = simcase(3,4,Cstring("hello"))
ccall((:printArray, "./test_array.so"), Void, ( Ptr{Float64}, Int32, Int32, simcase), x, Int32(n), Int32(m), s)

```

produces:

```julia
julia> ERROR: LoadError: MethodError: Cannot `convert` an object of type String to an object of type Cstring
This may have arisen from a call to the constructor Cstring(...),
since type constructors fall back to convert methods.
 in Cstring(::String) at ./sysimg.jl:53
 in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
 in macro expansion at ./REPL.jl:95 [inlined]
 in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68
while loading /home/nbecker/julia-test/test_array.jl, in expression starting on line 10

```

What’s the correct way to do this? I want the C code to get a structure containing a null-terminated C-string.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 24, 2017, 8:51pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/2 "2017-01-24T20:51:27Z")

</div>

Define `Base.cconvert`, `Base.unsafe_convert` to convert a normal julia object with a julia string to a C compatible object with `Cstring` field.  
e.g. with `immutable simcase` define `Base.cconvert(::Type{simcase}, v::Tuple) = (v[1], v[2], Base.cconvert(Cstring, v[3]))` and `Base.unsafe_convert(::Type{simcase}, v::Tuple) = simcase(v[1], v[2], Base.unsafe_convert(Cstring, v[3]))` and call the function with `ccall(..., (..., simcase), .., (3, 4, "hello"))`

---

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [January 25, 2017, 4:50pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/3 "2017-01-25T16:50:20Z")

</div>

I’m still struggling here. Let me try to ask again more clearly.

I need to pass a structure to C. One of the fields in the structure has to be a string which the C code will see as a C-string: an array of null-terminated bytes. So, in julia:

type simcase  
a::Int32  
s:: ???  
end

So I don’t know, maybe s is Array{UInt8,1}?

All julia has to do is fill in this field from a string literal.

Somehow when passed to C it needs to see:  
struct {  
int a;  
char\* s;  
};

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 25, 2017, 4:59pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/4 "2017-01-25T16:59:43Z")

</div>

That’s exactly the question I’m answering. Your original `simcase` is the correct type definition (just change it to `immutable` to simplify the `unsafe_convert` def a little bit).

---

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [January 25, 2017, 6:36pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/5 "2017-01-25T18:36:09Z")

</div>

OK, so I have this:

immutable simcase  
n::Int32  
m::Int32  
s::Cstring  
end

n = 2  
m = 3  
x = randn(n,m)

Base.cconvert(::Type{simcase}, v::Tuple) = (v[1], v[2], Base.cconvert(Cstring, v[3]))  
Base.unsafe\_convert(::Type{simcase}, v::Tuple) = simcase(v[1], v[2], Base.unsafe\_convert(Cstring, v[3]))  
ccall((:printArray, “./test\_array.so”), Void, ( Ptr{Float64}, simcase), x, (n, m, “hello”)) \<\< this works  
ccall((:printArray, “./test\_array.so”), Void, ( Ptr{Float64}, simcase), x, simcase(n, m, “hello”)) \<\< this doesn’t work

So I can manage to pass the structure to C as you show. But I will also need to create and manipulate simcase objects, which I don’t know how to do. And it’s not clear to me what’s different about the ccall above the works, and the ccall that doesn’t work (because explicitly tries to create a simcase object first).

For example:  
simcase (2, 3, “hi”)  
simcase(2,3,“hi”)  
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Cstring  
This may have arisen from a call to the constructor Cstring(…),  
since type constructors fall back to convert methods.  
in simcase(::Int64, ::Int64, ::String) at /home/nbecker/julia-test/test\_array.jl:2  
in eval\_user\_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64  
in macro expansion at ./REPL.jl:95 [inlined]  
in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 25, 2017, 6:50pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/6 "2017-01-25T18:50:01Z")

</div>

Right, you have to convert the object to C compatible layout when you pass it to C. The solution I gave just use a tuple as the input type for simplicity. If you want to use a special type for it instead of a tuple, you can just replace the tuple with it in the input of `cconvert`

```julia
type simcase_julia
    a::Int32
    b::Int32
    c::String
end
Base.cconvert(::Type{simcase}, v::simcase_julia) = (v.a, v.b, Base.cconvert(Cstring, v.c))

```

P.S. Please quote your code. See @ihnorton’s edit of your first post.

---

<div class="post-metadata">

**Author:** ![ndbecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ndbecker/32/10829_2.png) [@ndbecker](https://discourse.julialang.org/u/ndbecker)\
**Post date:** [January 25, 2017, 7:31pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/7 "2017-01-25T19:31:57Z")

</div>

Thanks! This seems to work:

```julia
immutable simcase_c
    n::Int32
    m::Int32
    s::Cstring
end

type simcase
    a::Int32
    b::Int32
    c::String
end
Base.cconvert(::Type{simcase_c}, v::simcase) = (v.a, v.b, Base.cconvert(Cstring, v.c))

n = 2
m = 3
x = randn(n,m)
Base.unsafe_convert(::Type{simcase_c}, v::Tuple) = simcase_c(v[1], v[2], Base.unsafe_convert(Cstring, v[3]))
ccall((:printArray, "./test_array.so"), Void, ( Ptr{Float64}, simcase_c), x, simcase(n, m, "hello"))

```

Although it works, I don’t understand what this means

```julia
Base.cconvert(::Type{simcase_c}, v::simcase) = (v.a, v.b, Base.cconvert(Cstring, v.c))

```

The result on the RHS is just a tuple.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 25, 2017, 8:15pm UTC](https://discourse.julialang.org/t/pass-structure-containing-string-to-c-code/1667/8 "2017-01-25T20:15:57Z")

</div>

See the [document](http://julia.readthedocs.io/en/latest/manual/calling-c-and-fortran-code/#auto-conversion) for what `unsafe_convert` and `cconvert` do.

I general, the return value of `unsafe_convert` should match what C want and that of `cconvert` should keep all julia references alive. The return value of `cconvert` will be given to `unsafe_convert` as argument. Since `cconvert` doesn’t have to match any ABI and only need to keep `cconvert(Cstring, ...)` alive, I’m just using a `Tuple` as return value for inconvenience (same reason why I used a tuple as input type for `cconvert` too).
