# Interpret \`NTuple{1024, UInt8}\` as a C string

**URL:** https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906
**Category:** General Usage
**Tags:** strings, interoperability
**Created:** [May 6, 2019, 11:10am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906 "2019-05-06T11:10:29Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)
#### Post date: [May 6, 2019, 11:10am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/1 "2019-05-06T11:10:29Z")

</div>

I am calling some C code. One of the structs has a field is of type `char [1024]`, which `Clang.jl` turns into `NTuple{1024,UInt8}`. This is a null-terminated C string.

How can I get a String-like thing from this without copying? I see there is `String(v::Array{UInt8,1})` or `String(v::AbstractArray{UInt8,1})`, but I have a tuple, not an array.

I was able to do

```julia
julia> data = (0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x00, 0x4f)
(0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x00, 0x4f)

julia> using StaticArrays

julia> String(SArray{Tuple{length(data)}}(data))
"base_chassis_joint\0O"

```

which possibly does not do any copying (not sure). But it doesn’t interpret the String as null-terminated.

If I could get a pointer to the data, then I can use `Cstring`, however the field is an `NTuple`, which has immutable semantics. I cannot call `pointer_from_objref` on it.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [May 6, 2019, 11:29am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/2 "2019-05-06T11:29:56Z")

</div>

I believe it is something like

```julia
unsafe_string(Ptr{UInt8}(pointer_from_objref(s) + fieldoffset(Cstruct, 1)))

```

where `s` is your struct instance and `1` is the field number of the string (here the type `Cstruct` just has the string as the first field).

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [May 6, 2019, 11:33am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/3 "2019-05-06T11:33:22Z")

</div>

You can use

```julia
mutable struct Foo
field1::Int 
stringfield::NTuple{1024, UInt8}
#...
end

```

and then use `pointer_from_objref(some_foo)+fieldoffset(Foo, 2)`. I am assuming that all your C functions actually operate on `Foo*` instead of `Foo`?

---

<div class="post-metadata">

### Author: ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)
#### Post date: [May 6, 2019, 11:34am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/4 "2019-05-06T11:34:18Z")

</div>

Thanks. In my case the struct `s` is immutable itself, because I was dereferencing the `Ref`. But perhaps, then, I should return the `Ref` if I want to use that.

Just to be concrete, this is what `Clang.jl` emits:

```julia
struct b3JointInfo
    m_linkName::NTuple{1024, UInt8}
    m_jointName::NTuple{1024, UInt8}
    m_jointType::Cint
    m_qIndex::Cint
    m_uIndex::Cint
    m_jointIndex::Cint
    m_flags::Cint
    m_jointDamping::Cdouble
    m_jointFriction::Cdouble
    m_jointLowerLimit::Cdouble
    m_jointUpperLimit::Cdouble
    m_jointMaxForce::Cdouble
    m_jointMaxVelocity::Cdouble
    m_parentFrame::NTuple{7, Cdouble}
    m_childFrame::NTuple{7, Cdouble}
    m_jointAxis::NTuple{3, Cdouble}
    m_parentIndex::Cint
    m_qSize::Cint
    m_uSize::Cint
end

```

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [May 6, 2019, 11:50am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/5 "2019-05-06T11:50:38Z")

</div>

You can use `pointer_from_objref(some::Base.RefValue{b3JointInfo})`.

---

<div class="post-metadata">

### Author: ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)
#### Post date: [May 8, 2019, 10:51am UTC](https://discourse.julialang.org/t/interpret-ntuple-1024-uint8-as-a-c-string/23906/6 "2019-05-08T10:51:12Z")

</div>

> [@goretkin](#):
>
> How can I get a String-like thing from this without copying?

The reason why Clang.jl emitted the code like this is that [there is no concise one-to-one correspondence between Julia structs and C structs](https://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#Struct-Type-Correspondences-1). We have to use `NTuple` to ensure alignment consistency. The copying is inevitable when your C function returns an instance of that type. If you don’t want that copying, your function has to return a pointer. A common pattern is to define an opaque struct like `typedef struct b3JointInfo* b3JointInfoHandle;` and access the string data via byte offset.
