# Calling C function expecting char\*\[\]

**URL:** <https://discourse.julialang.org/t/calling-c-function-expecting-char/12363>\
**Category:** General Usage\
**Created:** [July 14, 2018, 1:34am UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363 "2018-07-14T01:34:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [July 14, 2018, 1:34am UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/1 "2018-07-14T01:34:52Z")

</div>

I am trying to call the following function from a C library:

```nohighlight
int calceph_getconstantvs(t_calcephbin* eph, const char* name, t_calcephcharvalue *arrayvalue, int nvalue);

```

where:

```nohighlight
typedef char t_calcephcharvalue[CALCEPH_MAX_CONSTANTVALUE];

```

is the type of the function result for which the memory has to be allocated by the caller.

I have made easily a julia wrapper for a similar function which stores the result in a pre-allocated array of double:

```nohighlight
int calceph_getconstantvd(t_calcephbin* eph, const char* name, double *arrayvalue, int nvalue);

```

For the array of arrays of char, I have written the following code based on [Calling a C function from Julia and passing a 2D array as a pointer of pointers as argument - Stack Overflow](https://stackoverflow.com/questions/33003174/calling-a-c-function-from-julia-and-passing-a-2d-array-as-a-pointer-of-pointers) :

```julia
             storage = Array{UInt8}(CALCEPH_MAX_CONSTANTVALUE+1,numberOfValues)
             ptr = [Ref(storage,i) for i=1:size(storage,1):length(storage)]
             stat = ccall((:calceph_getconstantvs , libcalceph), Cint,
             (Ptr{Void},Ptr{UInt8},Ptr{Ptr{UInt8}}, Cint),
             eph.data, name ,ptr, numberOfValues)

```

but I get a segmentation fault when I run this code.

---

<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:** [July 14, 2018, 1:52am UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/2 "2018-07-14T01:52:30Z")

</div>

> expecting char\*

No it doesn’t…

So as much as most people (me included) tend to believe otherwise, pointers and arrays are **NOT** the same in C and this is one of the few cases this difference matters.

Basically, `t_calcephcharvalue` is an array type and `t_calcephcharvalue*` is a pointer to the **array** type and **not** the **pointer** type. Or in another word, the type of `arrayvalue[0]` is an array and **not** a pointer and the offset between the address of `arrayvalue[0]`and `arrayvalue[1]` is the size of `t_calcephcharvalue` and not `char*`. Or in yet another word, `arrayvalue` points to a piece of memory that is holding many (an array of) fixed length strings (each with length `CALCEPH_MAX_CONSTANTVALUE`) laid right next to each other. It does **NOT** point to an array of pointers pointing to the strings.

With that in mind, what you need should be `storage = Array{UInt8}(CALCEPH_MAX_CONSTANTVALUE, numberOfValues)` and pass storage directly to the C function with argument type `Ptr{UInt8}`.

P.S. C array and pointer can easily be confusing. It usually makes sense but I usually check to make sure since it’s so rarely used (for me). LLVM IR is a pretty good way to check this.

```julia
yyc:~/tmp
yuyichao% cat a.c
//

typedef int ta[10];

int f(ta *p)
{
    return p[0][0];
}
yyc:~/tmp
yuyichao% clang -emit-llvm a.c -o - -O3 -S
; ModuleID = 'a.c'
source_filename = "a.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: norecurse nounwind readonly sspstrong uwtable
define i32 @f([10 x i32]* nocapture readonly) local_unnamed_addr #0 {
  %2 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i64 0, i64 0
  %3 = load i32, i32* %2, align 4, !tbaa !4
  ret i32 %3
}

```

As you can see, the LLVM IR only has one load with a single offset calculation.

---

<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:** [July 14, 2018, 1:58am UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/3 "2018-07-14T01:58:20Z")

</div>

P.P.S. I believe the correct way to spell that argument type is `char [][N]` as in `char arrayvalue[][N]` (with N being the constant size).

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [July 14, 2018, 1:19pm UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/4 "2018-07-14T13:19:29Z")

</div>

Thank you very much. It works now.

```julia
storage = Array{UInt8}(_maxConstValue,numberOfValues)
stat = ccall((:calceph_getconstantvs , libcalceph), Cint,
             (Ptr{Void},Ptr{UInt8},Ptr{UInt8}, Cint),
             eph.data, name ,storage, numberOfValues)
values = [strip(unsafe_string(pointer(storage,i))) for i in 1:_maxConstValue:length(storage)]

```

---

<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:** [July 15, 2018, 6:47pm UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/5 "2018-07-15T18:47:48Z")

</div>

> [@Bernard\_GODARD](#):
>
> `storage = Array{UInt8}(_maxConstValue,numberOfValues)`

It seems that what you really want is an array of pointers, e.g.

```julia
storage = Array{Ptr{UInt8}}(numberOfValues)
stat = ccall((:calceph_getconstantvs, libcalceph), Cint,
             (Ptr{Void},Cstring,Ptr{Ptr{UInt8}}, Cint),
             eph.data, name, storage, numberOfValues)
values = strip.(unsafe_string.(storage))

```

---

<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:** [July 15, 2018, 7:45pm UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/6 "2018-07-15T19:45:37Z")

</div>

> [@stevengj](#):
>
> It seems that what you really want is an array of pointers, e.g.

No!

Please, read my full post. That’s exactly why I described the problem in all different ways I could think of, in particular,

> [@yuyichao](#):
>
> It does **NOT** point to an array of pointers pointing to the strings.

---

<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:** [July 15, 2018, 7:47pm UTC](https://discourse.julialang.org/t/calling-c-function-expecting-char/12363/7 "2018-07-15T19:47:10Z")

</div>

> [@stevengj](#):
>
> calceph\_getconstantvs

See also [Multiple file access functions — CALCEPH - C language 3.5.4 documentation](https://www.imcce.fr/content/medias/recherche/equipes/asd/calceph/html/c/calceph.multiple.html#c.calceph_getconstantvs) in particular

```c++
  mission_units = (t_calcephcharvalue*)malloc(sizeof(t_calcephcharvalue)*nvalue);

  /* fill the array radii */
  if (calceph_getconstantvs(peph, "MISSION_UNITS", mission_units, nvalue))

```
