# Pass vectors by reference using CxxWrap.@safe\_cfunction

**URL:** <https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350>\
**Category:** General Usage\
**Tags:** cxxwrap\
**Created:** [July 22, 2024, 4:29pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350 "2024-07-22T16:29:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![afossa](https://avatars.discourse-cdn.com/v4/letter/a/eb9ed0/32.png) [@afossa](https://discourse.julialang.org/u/afossa)\
**Post date:** [July 22, 2024, 4:29pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/1 "2024-07-22T16:29:07Z")

</div>

Hello,  
I have a Julia function like

```julia
function f(x::AbstractVector{Float64}, y::AbstractVector{Float64})
    y[1] = 2.0*x[1];
    y[2] = 2.0*x[2];
    return nothing;
end;

```

which takes in input two arrays of `Float64` and modifies the second one in place.

I am trying to use `CxxWrap` to evaluate this function with `x` and `y` as `std::vector<double>`, but I haven’t been able to succeed so far.

On the C++ side I have:

```cpp
JLCXX_MODULE define_julia_module(jlcxx::Module& mod) {

    mod.method("call_val", [](void(*func)(std::vector<double>, std::vector<double>)) {
        std::vector<double> x = {1.0, 2.0};
        std::vector<double> y(x.size());
        func(x, y);
        return y;
    });

    mod.method("call_ref", [](void(*func)(std::vector<double>&, std::vector<double>&)) {
        std::vector<double> x = {1.0, 2.0};
        std::vector<double> y(x.size());
        func(x, y);
        return y;
    });
}

```

while on the Julia side:

```julia
f_val_c = @safe_cfunction(f, Cvoid, (CxxWrap.StdLib.StdVectorAllocated{Float64}, CxxWrap.StdLib.StdVectorAllocated{Float64},));
f_ref_c = @safe_cfunction(f, Cvoid, (CxxRef{CxxWrap.StdLib.StdVectorAllocated{Float64}}, CxxRef{CxxWrap.StdLib.StdVectorAllocated{Float64}},));

a = call_val(f_val_c);
println(a);

b = call_ref(f_ref_c);
println(b);

```

the first option doesn’t throw any error, but since `y` is passed by value to `func`, I have no way to use the outcome of the function evaluation.

In the second case, I get this error:

```julia
ERROR: Incorrect argument type for cfunction at position 1, expected: CxxRef, obtained: CxxRef

```

I tried to modify the signature passed to `@safe_cfunction` in few different ways, but none seems to work.

Do you have any suggestion?

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [July 22, 2024, 5:51pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/2 "2024-07-22T17:51:18Z")

</div>

Hi @afossa !

See the section “Working with arrays” in the CxxWrap documentation here:

> **[GitHub - JuliaInterop/CxxWrap.jl: Package to make C++ libraries available in...](https://github.com/JuliaInterop/CxxWrap.jl)**
>
> Package to make C++ libraries available in Julia. Contribute to JuliaInterop/CxxWrap.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![afossa](https://avatars.discourse-cdn.com/v4/letter/a/eb9ed0/32.png) [@afossa](https://discourse.julialang.org/u/afossa)\
**Post date:** [July 22, 2024, 7:14pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/3 "2024-07-22T19:14:49Z")

</div>

Thanks @Ronis_BR  
I have already checked out the documentation multiple times, but there is no answer for my particular case.

My final objective is to write a Julia interface to a C++ library. This library has some methods which expect as input a function with signature:

```cpp
std::vector<double> f(const std::vector<double>&) const;

```

such that they can evaluate it on `std::vector<double>` created and managed in C++. I am not interested in evaluating `f` on some Julia arrays, nor to immediately retrieve the output of the function evaluation, since it will be stored in a C++ `class` I will be able to query later.

In the example above I rewrote `f` as an inplace function because it seemed easier for me to interface, and then I can just define a wrapper around it in C++ to match the expected signature.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [July 22, 2024, 11:37pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/4 "2024-07-22T23:37:25Z")

</div>

I see. In this case, maybe the easiest option would be to keep everything in C++ and use CxxWrap to create the interfaces for mutating the values. Those interfaces will receive the values that must be applied to the `std::vector`. Would it work for your use case?

---

<div class="post-metadata">

**Author:** ![afossa](https://avatars.discourse-cdn.com/v4/letter/a/eb9ed0/32.png) [@afossa](https://discourse.julialang.org/u/afossa)\
**Post date:** [July 23, 2024, 2:03am UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/5 "2024-07-23T02:03:25Z")

</div>

As long as I can define my function in Julia, and I can evaluate it also on a regular Julia `Vector{Float64}` (for testing, comparison, etc.), I think it will work. Could you clarify a bit more what you mean?

I would also like to minimize allocations and copying values between Julia and C++ vectors, since these can be quite large in size.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [July 23, 2024, 12:26pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/6 "2024-07-23T12:26:28Z")

</div>

I am doing like this:

1. I create a singleton in C++ to load and store any C++ value.
2. I create interfaces to send and receive those values in Julia.

Hence, instead of having a function that will modify the elements in place, you would pass the elements (like integers) and the C++ function will change inside the vector. It works perfectly for me, but it can be hard / impossible if you need to send / receive a lot of values.

---

<div class="post-metadata">

**Author:** ![afossa](https://avatars.discourse-cdn.com/v4/letter/a/eb9ed0/32.png) [@afossa](https://discourse.julialang.org/u/afossa)\
**Post date:** [July 23, 2024, 7:51pm UTC](https://discourse.julialang.org/t/pass-vectors-by-reference-using-cxxwrap-safe-cfunction/117350/7 "2024-07-23T19:51:37Z")

</div>

For now I came up with this solution:

On the C++ side I have

```cpp
typedef std::function<std::vector<double>(const std::vector<double>&)> function_t;

function_t make_callable(void *f, size_t n) {
  auto g = reinterpret_cast<void(*)(const double*, double*)>(f);
  return [g,n](const std::vector<double>& x) {
    auto x_ptr = x.data();
    auto y = std::vector<double>(n);
    auto y_ptr = y.data();
    g(x_ptr, y_ptr);
    return y;
  };
}

JLCXX_MODULE define_julia_module(jlcxx::Module& mod) {
    mod.method("eval", [](void *f, jlcxx::ArrayRef<double> a, const size_t n) {
        auto g = make_callable(f, n);
        const std::vector<double> x(a.begin(), a.end());
        return g(x);
    });
}

```

while in Julia I do

```julia
function f!(y::T, x::T) where T<:AbstractVector{Float64}
    y[1] = 5.0*x[1];
    y[2] = 7.0*x[2];
    return nothing;
end;

function fwrap!(f!::Function, x_ptr::Ptr{Float64}, y_ptr::Ptr{Float64}, n::Integer, m::Integer)
    x = unsafe_wrap(Array, x_ptr, n);
    y = unsafe_wrap(Array, y_ptr, m);
    f!(y,x);
    return nothing;
end;

v = [2.0, 3.0];
n = 2;
y = zeros(Float64, n);
f!(y,v);
println(y);

fwrap_c = @cfunction((x,y) -> fwrap!(f!,x,y,n,n), Cvoid, (Ptr{Float64}, Ptr{Float64}));
y_c = eval(fwrap_c, v, n);
println(y_c);

```

I am not sure if it is the best solution, but it works.

I also tried with `@safe_cfunction` instead of the bare `@cfunction`, e.g.

```julia
fwrap_cs = @safe_cfunction((x,y) -> fwrap!(f!,x,y,n,n), Cvoid, (Ptr{Float64}, Ptr{Float64}));
y_cs = eval(fwrap_cs, v, n);
println(y_cs);

```

and then

```cpp
function_t make_callable(jlcxx::SafeCFunction f, size_t n) {
  auto g = jlcxx::make_function_pointer<void(const double*, double*)>(f);
  return [g,n](const std::vector<double>& x) {
    auto x_ptr = x.data();
    auto y = std::vector<double>(n);
    auto y_ptr = y.data();
    g(x_ptr, y_ptr);
    return y;
  };
}

JLCXX_MODULE define_julia_module(jlcxx::Module& mod) {
    mod.method("eval", [](jlcxx::SafeCFunction f, jlcxx::ArrayRef<double> a, const size_t n) {
        auto g = make_callable(f, n);
        const std::vector<double> x(a.begin(), a.end());
        return g(x);
    }, "Evaluates `arg1` on `arg2` returning an array of size `arg3`.");
}

```

but in this case I get a cryptic error `Type Pd has no Julia wrapper`
