# Calling a c-function that returns a 2-dimensional array

**URL:** <https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 11, 2016, 4:24am UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855 "2016-12-11T04:24:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![peter](https://avatars.discourse-cdn.com/v4/letter/p/278dde/32.png) [@peter](https://discourse.julialang.org/u/peter)\
**Post date:** [December 11, 2016, 4:24am UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/1 "2016-12-11T04:24:09Z")

</div>

Hello,

new to julia. I want to call a c-function like

```julia
void foo(double a[], double b[], double c[][n], int n){
    for (int i=0; i<n; i++){
        for (int j=0; j<n; j++){
            c[i][j]=a[i]*b[j];
        }   
    }
 }

```

from julia.

In julia I have defined the input arrays and will declare the output array, that has two dimensions from the same size. For examble:

```julia
n = 5
a = ones(n)
b = fill(2,n)
c = Array{Float64}(n,n)

```

What are the correct parameters for ccall to fill the output array by the c-function?

Thank’s

peter

---

<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:** [December 11, 2016, 4:30am UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/2 "2016-12-11T04:30:42Z")

</div>

`Ptr{Float64}` \<20 char limits…\>

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 11, 2016, 5:43am UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/3 "2016-12-11T05:43:29Z")

</div>

This tutorial may be helpful?

> **[Using Julia's C Interface to Utilize C Libraries - Stochastic Lifestyle](http://www.stochasticlifestyle.com/using-julias-c-interface-utilize-c-libraries/)**
>
> I recently ran into the problem that Julias's (GNU Scientific Library) GSL.jl library is too new, i.e. some portions don't work as of early 2016. However, to solve my problem I needed access to adaptive Monte Carlo integration methods. This means it...

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [December 11, 2016, 12:42pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/4 "2016-12-11T12:42:17Z")

</div>

I think the following should work:

```julia
assert(n == size(c,1) == size(c,2))
ccall((:foo, libname), Void, 
    (Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Ptr{Cdouble}}, Cint), 
    a, b, [view(c,:,j) for j = 1:n], n)

```

Note that Julia uses column-major ordering, so you may need to transpose the result.

UPDATE: this is incorrect: see comments by @yuyichao and @jameson below

---

<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:** [December 11, 2016, 1:39pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/5 "2016-12-11T13:39:04Z")

</div>

No it’s just a `Ptr{Cdouble}`.

---

<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:** [December 11, 2016, 2:04pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/6 "2016-12-11T14:04:50Z")

</div>

I assume the OP knows how to pass simple types and how to map them to julia types and only have questions about passing a multidimensional array.

Passing a multidimensional array (or multidimensional array) in C is surprisingly underdocumented AFAICT. I can’t find any clear mention on cppreference (though there’re hints). The best I can find apart from many SO posts that covers parts of the problem each is [23.1: Multidimensional Arrays and Functions](https://www.eskimo.com/~scs/cclass/int/sx9a.html) .

It might worth mentioning this in our doc. It’s worth noting that `int a[2][2]` and `int a**` are completely different types in C even though both of them are dereferenced with `a[x][y]`. They have very different type layout and cannot be converted to each other.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [December 14, 2016, 5:54pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/7 "2016-12-14T17:54:55Z")

</div>

> Passing a multidimensional array (or multidimensional array) in C is surprisingly underdocumented AFAICT

Declaring a C argument type as being `[]`, I believe, is a compiler extension (although probably part of the spec now), and isn’t actually part of the C ABI. Most parsers rewrite any number of `[]` to `*` in the argument list following the rules for array-pointer decomposition. This isn’t strictly valid, but the direct interpretation of this syntax (passing an array by-value) isn’t defined in the C standard.

---

<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:** [December 14, 2016, 6:26pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/8 "2016-12-14T18:26:32Z")

</div>

> [@jameson](#):
>
> Declaring a C argument type as being , I believe, is a compiler extension (although probably part of the spec now), and isn’t actually part of the C ABI.

Passing array argument is actually mentioned on cppreference [Array declaration - cppreference.com](http://en.cppreference.com/w/c/language/array) and I just noticed that passing in multi dimensional array is actually also mentioned in there to, which is supported since c99.

---

<div class="post-metadata">

**Author:** ![peter](https://avatars.discourse-cdn.com/v4/letter/p/278dde/32.png) [@peter](https://discourse.julialang.org/u/peter)\
**Post date:** [December 14, 2016, 7:52pm UTC](https://discourse.julialang.org/t/calling-a-c-function-that-returns-a-2-dimensional-array/855/9 "2016-12-14T19:52:47Z")

</div>

> [@yuyichao](#):
>
> I assume the OP knows how to pass simple types and how to map them to julia types and only have questions about passing a multidimensional array.

Yes, only passing multi-dimensional arrays I find confusing.

Thanks, it’s really a Ptr{Cdouble}. The array have to be transposed before and after the call, as simonbyrne sayed.

For example:

C:

```julia
void foo(double c[][4], int n)
{
    int i,j;
    printf("called with\n");
    for(i=0; i<n; i++) {
	for(j=0; j<n; j++) {
            printf("%f ",c[i][j]);
        }
        printf("\n");
    }
    for(i=0; i<n; i++) {
	for(j=0; j<n; j++) {
            c[i][j]=c[i][j]*10;
        }
    }

    printf("returnd with \n"); 
    for(i=0; i<n; i++) {
		for(j=0; j<n; j++) {
            printf("%f ",c[i][j]);
        }
        printf("\n");
    } 
}

```

julia:

```julia
julia> n=4
4

julia> c=[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16.]
4×4 Array{Float64,2}:
  1.0 2.0 3.0 4.0
  5.0 6.0 7.0 8.0
  9.0 10.0 11.0 12.0
 13.0 14.0 15.0 16.0

julia> ct=transpose(c)
4×4 Array{Float64,2}:
 1.0 5.0 9.0 13.0
 2.0 6.0 10.0 14.0
 3.0 7.0 11.0 15.0
 4.0 8.0 12.0 16.0

julia> ccall((:foo,"foolib.so"), Void,
           (Ptr{Cdouble}, Cint), ct, n)
called with
1.000000 2.000000 3.000000 4.000000
5.000000 6.000000 7.000000 8.000000
9.000000 10.000000 11.000000 12.000000
13.000000 14.000000 15.000000 16.000000
returns with
10.000000 20.000000 30.000000 40.000000
50.000000 60.000000 70.000000 80.000000
90.000000 100.000000 110.000000 120.000000
130.000000 140.000000 150.000000 160.000000

julia> ct
4×4 Array{Float64,2}:
 10.0 50.0 90.0 130.0
 20.0 60.0 100.0 140.0
 30.0 70.0 110.0 150.0
 40.0 80.0 120.0 160.0

julia> c=transpose(ct)
4×4 Array{Float64,2}:
  10.0 20.0 30.0 40.0
  50.0 60.0 70.0 80.0
  90.0 100.0 110.0 120.0
 130.0 140.0 150.0 160.0

```

peter
