# CxxWrap tutorial - matrix input and output args

**URL:** <https://discourse.julialang.org/t/cxxwrap-tutorial-matrix-input-and-output-args/93336>\
**Category:** New to Julia\
**Created:** [January 21, 2023, 8:32pm UTC](https://discourse.julialang.org/t/cxxwrap-tutorial-matrix-input-and-output-args/93336 "2023-01-21T20:32:05Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![frli8848](https://avatars.discourse-cdn.com/v4/letter/f/d78d45/32.png) [@frli8848](https://discourse.julialang.org/u/frli8848)\
**Post date:** [January 21, 2023, 8:32pm UTC](https://discourse.julialang.org/t/cxxwrap-tutorial-matrix-input-and-output-args/93336/1 "2023-01-21T20:32:05Z")

</div>

Hi All,

I’m trying to create Julia bindings using CxxWrap for a project ([GitHub - frli8848/DREAM: The DREAM toolbox is a free open source acoustic field simulation tool](https://github.com/frli8848/DREAM)). Is there a good tutorial on how to do this? I basically want to:

- Parse each input arg and check for correctness, for example matrix dims (number of rows, cols) etc.
- Allocate space for the output matrix,
- call my C++ function,
- return the matrix to Julia.

I want to have a pointers to the (Julia) matrix data buffers (double arrays) which I can pass directly to my functions and avoid any copying of possible large buffers.

I assume Fortran style matrices (column major). I have looked at the CxxWrap README:s on github and some julia header files (array.hpp etc) but I have not found any good way to do this.

Regards,

/Fredrik

PS. I have bindings for MATLAB, Octave, and Python

---

<div class="post-metadata">

**Author:** ![frli8848](https://avatars.discourse-cdn.com/v4/letter/f/d78d45/32.png) [@frli8848](https://discourse.julialang.org/u/frli8848)\
**Post date:** [January 23, 2023, 7:50am UTC](https://discourse.julialang.org/t/cxxwrap-tutorial-matrix-input-and-output-args/93336/2 "2023-01-23T07:50:33Z")

</div>

I tried something like this (similar to the pybind11 code that I use for the Python bindings):

```julia
jl::ArrayRef<double> jl_dreamrect(jl::ArrayRef<double> *jl_ro,
                                     jl::ArrayRef<double> *jl_geom_par,
                                     jl::ArrayRef<double> *jl_s_par,
                                     jl::ArrayRef<double> *jl_delay,
                                     jl::ArrayRef<double> *jl_m_par,
                                     std::string err_level_str)
{

-snip-

  // Create an output matrix for the impulse responses
  jl_value_t *matrix_type = jl_apply_array_type((jl_value_t*) jl_float64_type,2);
  jl_array_t *jl_h_mat = jl_alloc_array_2d(matrix_type, nt, no);
  double *h = (double *) jl_array_data(jl_h_mat);
  //auto jl_h_mat = jl::Array<double>(nt*no);

-snip-

  return jl_h_mat;
}

JLCXX_MODULE define_julia_module(jlcxx::Module& mod)
{
  mod.method("dreamrect", &jl_dreamrect);
}

```

And then try to load the .so using:

```julia
module dr
using CxxWrap
@wrapmodule(joinpath("/home/fl/projects/DREAM/build/julia","dreamrect"))
function __init__ ()
    @initcxx
end
end

```

and I got this Julia output:

```julia
julia> include("/home/fl/projects/DREAM/julia/tests/test_dreamrect.jl")
WARNING: replacing module dr.
ERROR: LoadError: MethodError: no method matching rem(::String, ::Tuple{Int64, Int64, Float64})
Closest candidates are:
  rem(::Any, ::Any, ::RoundingMode{:ToZero}) at div.jl:83
  rem(::Any, ::Any, ::RoundingMode{:Down}) at div.jl:84
  rem(::Any, ::Any, ::RoundingMode{:Up}) at div.jl:85
  ...
Stacktrace:
 [1] include(fname::String)
   @ Base.MainInclude ./client.jl:476
 [2] top-level scope
   @ REPL[15]:1
in expression starting at /home/fl/projects/DREAM/julia/tests/test_dreamrect.jl:28

```

I have no idea what this means?

---

<div class="post-metadata">

**Author:** ![frli8848](https://avatars.discourse-cdn.com/v4/letter/f/d78d45/32.png) [@frli8848](https://discourse.julialang.org/u/frli8848)\
**Post date:** [January 23, 2023, 12:02pm UTC](https://discourse.julialang.org/t/cxxwrap-tutorial-matrix-input-and-output-args/93336/3 "2023-01-23T12:02:21Z")

</div>

I got it to work by looking closer to the `julia.h` and `array.hpp` header files. Apparently Julia is using different data types for vectors and matrices (why?) and one should not use pointers to `ArrayRef<double>`s as function arguments. So the glue function should be:

```julia
jl::ArrayRef<double, 2> jl_dreamrect(jl::ArrayRef<double, 2> jl_ro,
                                     jl::ArrayRef<double> jl_geom_par,
                                     jl::ArrayRef<double> jl_s_par,
                                     jl::ArrayRef<double> jl_delay,
                                     jl::ArrayRef<double> jl_m_par,
                                     std::string err_level_str);

```

where `jl::ArrayRef<double, 2>` is a (2D) matrix and ` jl::ArrayRef<double` is a vector. To get vector and matrix dims, and data pointers one can do:

```julia
// Vector
 dream_idx_type get_len(const jl::ArrayRef<double> &jl_arg) {
    auto len = jl_array_len(jl_arg.wrapped());
    return (dream_idx_type) len;
  };

  // Matrix
  dream_idx_type get_m(const jl::ArrayRef<double, 2> &jl_arg) {
    auto m = jl_arg.wrapped()->nrows;
    return (dream_idx_type) m;
  };

  // Matrix
  dream_idx_type get_n(const jl::ArrayRef<double, 2> &jl_arg) {
    auto n = jl_arg.wrapped()->ncols;
    return (dream_idx_type) n;
  };

  // Vector
  double* get_data(const jl::ArrayRef<double> &jl_arg) {
    return static_cast<double*>(jl_array_data(jl_arg.wrapped()));
  };

  // Matrix
  double* get_data(const jl::ArrayRef<double, 2> &jl_arg) {
    return static_cast<double*>(jl_array_data(jl_arg.wrapped()));
  };

```
