# Question on ccall for complex types

**URL:** <https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024>\
**Category:** General Usage\
**Tags:** ccall\
**Created:** [September 21, 2017, 2:28pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024 "2017-09-21T14:28:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [September 21, 2017, 2:28pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/1 "2017-09-21T14:28:28Z")

</div>

We are getting deprecation warnings for uses of & in ccall’s in Nemo.jl. It’s time we replaced them, but I don’t currently understand what is required.

To make the question concrete, I give an example. On the C side we basically have a struct, called fmpz\_poly, say. Various functions take pointers to such structs as both inputs and as outputs, e.g. we have functions which effectively look like this:

```julia
/* set r = a + b */
void fmpz_poly_add(fmpz_poly * r, const fmpz_poly * a, const fmpz_poly * c)
{
/* ... */
}

```

On the Julia side, we define:

```julia
type fmpz_poly
   # some fields
end

```

Now we wish to pass fmpz\_poly’s created on the Julia side, to the C function fmpz\_poly\_add say, safely and efficiently.

At present we do the following:

```julia
function +(a::fmpz_poly, b::fmpz_poly)
   r = fmpz_poly()
   ccall((:fmpz_poly_add, :libflint), Void, (Ptr{fmpz_poly}, Ptr{fmpz_poly}, Ptr{fmpz_poly}), &r, &a, &b)
   return r
end

```

The recommendation seems to be to use Ref{fmpz\_poly} instead of & and Ptr{fmpz\_poly}. But I want to understand what this is doing.

The documentation says that Ref{fmpz\_poly} prevents Julia gc from cleaning up the reference until there is no longer any reference to the Ref itself. However, the ccall interface also says that it maintains a reference to its arguments to prevent gc whilst the ccall is being executed. And it says that the Ref argument is converted to a native pointer before passing to the C side (by calling some function for this purpose).

This confuses me, since I don’t see the purpose of using a Ref, since the arguments to ccall are automatically protected from gc.

Basically, I can’t tell from the documentation which of the following is expected, and what the performance ramifications of each solution is (or whether they are valid Julia):

```julia
function +(a::fmpz_poly, b::fmpz_poly)
   r = fmpz_poly()
   reff = Ref{fmpz_poly}(r)
   refa = Ref{fmpz_poly}(a)
   refb = Ref{fmpz_poly}(b)
   ccall((:fmpz_poly_add, :libflint), Void, (Ref{fmpz_poly}, Ref{fmpz_poly}, Ref{fmpz_poly}), refr, refa, refb)
   return r
end

```

```julia
function +(a::fmpz_poly, b::fmpz_poly)
   r = fmpz_poly()
   ccall((:fmpz_poly_add, :libflint), Void, (Ref{fmpz_poly}, Ref{fmpz_poly}, Ref{fmpz_poly}), 
          Ref{fmpz_poly}(r), Ref{fmpz_poly}(a), Ref{fmpz_poly}(b))
   return r
end

```

```julia
function +(a::fmpz_poly, b::fmpz_poly)
   r = fmpz_poly()
   ccall((:fmpz_poly_add, :libflint), Void, (Ref{fmpz_poly}, Ref{fmpz_poly}, Ref{fmpz_poly}), r, a, b)
   return r
end

```

Clearly, we do need Julia to not gc cleanup the objects a, b and r whilst the ccall is in effect. But our entire library is full of ccalls and we obviously want to do things as efficiently as possible. So which of the above is the best strategy?

---

<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:** [September 21, 2017, 2:43pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/2 "2017-09-21T14:43:47Z")

</div>

> [@wbhart](#):
>
> The documentation says that Ref{fmpz\_poly} prevents Julia gc from cleaning up the reference until there is no longer any reference to the Ref itself

Ref is not doing that. That part of the doc seems to be more confusing than helping.

> [@wbhart](#):
>
> since the arguments to ccall are automatically protected from gc.

This is not true. Properly defined `cconvert` and `unsafe_convert` prevents that.

> [@wbhart](#):
>
> Basically, I can’t tell from the documentation which of the following is expected, and what the performance ramifications of each solution is (or whether they are valid Julia):

All of them are equivalent and should have the same performance. The first two are exactly the same. There’s no significance of assigning to a local variable.

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [September 21, 2017, 3:24pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/3 "2017-09-21T15:24:26Z")

</div>

To quote the (latest) documentation:

> ccall automatically arranges that all of its arguments will be preserved from garbage collection until the call returns.

You mentioned cconvert and unsafe\_convert. Am I supposed to define these for my types, or are there sensible Julia defaults that will do the job in most cases?

---

<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:** [September 21, 2017, 3:37pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/4 "2017-09-21T15:37:38Z")

</div>

There’s no “sensible Julia defaults”. There are specific meanings when you use `Ref` as arguments type that must not be overwriten. If the convertion you want is not passing a type by reference, you may need to define your own to do that and you must not use a type combination that conflicts with the base one. (i.e. the three pieces of code should call the base definition to pass `::fmpz_poly` by reference, if you want to do something else using auto conversion, you must not use `Ref{fmpz_poly}` as the ccall argument types).

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [September 21, 2017, 4:03pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/5 "2017-09-21T16:03:22Z")

</div>

Just to clarify what I think you are saying: there is no need to supply definitions of cconvert and unsafe\_convert in any of the three code examples I gave, for my types, (assuming I want the values to be passed by reference).

---

<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:** [September 21, 2017, 4:20pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/6 "2017-09-21T16:20:27Z")

</div>

I’m saying it is invalid to supply cconvert and unsafe\_convert definitions for the code you have

---

<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:** [September 21, 2017, 4:22pm UTC](https://discourse.julialang.org/t/question-on-ccall-for-complex-types/6024/7 "2017-09-21T16:22:42Z")

</div>

Or in another word, there is a sensible definition but it is not the default, it is the only valid definition. You must not provide your own using the same types
