# Wrapping C++ class

**URL:** https://discourse.julialang.org/t/wrapping-c-class/102573
**Category:** General Usage
**Tags:** c
**Created:** [August 7, 2023, 4:26pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573 "2023-08-07T16:26:31Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [August 7, 2023, 4:26pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/1 "2023-08-07T16:26:31Z")

</div>

Okay, I have a MWE that duplicates my issue: My wrapper correctly gives me the main application. The main application manages some other classes as members, but when I get those members back - they seem to not work. This example has a main class that has two member classes. One class just manages an integer, the other one manages a double. I wrote a C wrapper around the C++ library, and a C application that uses the wrapper works as expected - but there is something wrong with how I did it in Julia.

I squished all of the code together because it just made the question harder to read.  
I expected to be able to run the julia wrapper with:

```julia
m = MainApp(1, 3.5)
a = m.borrowA()
a.get_id() # should yield 1, yields garbage

b = m.borrowB()
b.get_s() # should yield 3.5, yields garbage

```

> **C++ "library"**
>
> ```cpp
> // stuff.h
> class A {
> private:
> int id;
> 
> public:
> A(int id);
> int get_id() const;
> };
> 
> class B {
> private:
> double s;
> 
> public:
> B(double s);
> double get_s() const;
> };
> 
> class MainApp {
> private:
> A myA;
> B myB;
> 
> public:
> A* borrowA();
> B* borrowB();
> 
> MainApp(int one, double two);
> };
> 
> ```
> 
> ```cpp
> // stuff.cpp
> #include "stuff.h"
> 
> A::A(int id) : id(id) {};
> int A::get_id() const { return id; }
> 
> B::B(double s) : s(s) {};
> double B::get_s() const { return s; }
> 
> MainApp::MainApp(int one, double two) : myA(one), myB(two) {}
> A *MainApp::borrowA() { return &myA; }
> B *MainApp::borrowB() { return &myB; }
> 
> ```

> **C wrapper**
>
> ```plaintext
> #include "wrap_stuff.h"
> #include <new>
> 
> H_mainapp *MainApp_create(int a, double b) {
> return reinterpret_cast<H_mainapp *>(new (std::nothrow) MainApp(a, b));
> }
> 
> void MainApp_destroy(H_mainapp *m) {
> MainApp *p = reinterpret_cast<MainApp *>(m);
> delete p;
> }
> 
> H_A *MainApp_borrow_A(H_mainapp *m) {
> MainApp *p = reinterpret_cast<MainApp *>(m);
> return reinterpret_cast<H_A *>(p->borrowA());
> }
> 
> H_B *MainApp_borrow_B(H_mainapp *m) {
> MainApp *p = reinterpret_cast<MainApp *>(m);
> return reinterpret_cast<H_B *>(p->borrowB());
> }
> 
> int A_get_id(H_A *a) {
> A *aa = reinterpret_cast<A *>(a);
> return aa->get_id();
> }
> 
> double B_get_s(H_B *b) {
> B *bb = reinterpret_cast<B *>(b);
> return bb->get_s();
> }
> 
> ```

> **Build Script for Libraries**
>
> ```bash
> #!/usr/bin/bash
> 
> g++ -shared -fPIC stuff.cpp -o libstuff.so
> 
> g++ -shared -fPIC wrap_stuff.cpp -o libstuff_wrapper.so \
> -Wl,-rpath=. -L. -lstuff
> 
> gcc test_c_interface.c -o test_c_interface \
> -Wl,-rpath=. -L. -lstuff_wrapper
> 
> ```

Lastly,

> **Julia code to use the library**
>
> ```julia
> mutable struct MainApp
> p::Ptr{Cvoid}
> 
> function MainApp(a, b)
> obj = @ccall "libstuff_wrapper.so".MainApp_create(a::Cint, b::Cdouble)::Ptr{Cvoid}
> if obj != C_NULL
> g = new(obj)
> finalizer(x -> ccall((:MainApp_destroy, "libstuff_wrapper.so"), Cvoid, (Ptr{Cvoid},), x.p), g)
> else
> error("Can't create MainApp");
> end
> end
> end
> 
> function Base.getproperty(this::MainApp, s::Symbol)
> if s == :borrowA
> function()
> ah = @ccall "libstuff_wrapper.so".MainApp_borrow_A()::Ptr{Cvoid}
> @show ah
> A(ah)
> end
> elseif s == :borrowB
> function()
> B(@ccall "libstuff_wrapper.so".MainApp_borrow_B()::Ptr{Cvoid})
> end
> else
> getfield(this, s)
> end
> end
> 
> #------------------------------------------------------------------------------#
> mutable struct A
> p::Ptr{Cvoid}
> 
> function A(x::Ptr{Cvoid})
> x == C_NULL && throw(error("argument cannot be C_NULL"))
> new(x)
> end
> end
> 
> function Base.getproperty(this::A, s::Symbol)
> @show s
> if s == :get_id
> function()
> @ccall "libstuff_wrapper.so".A_get_id()::Cint
> end
> else
> getfield(this, s)
> end
> end
> 
> #------------------------------------------------------------------------------#
> mutable struct B
> p::Ptr{Cvoid}
> 
> function B(x::Ptr{Cvoid})
> x == C_NULL && throw(error("argument cannot be C_NULL"))
> new(x)
> end
> end
> 
> function Base.getproperty(this::B, s::Symbol)
> if s == :get_s
> function()
> @ccall "libstuff_wrapper.so".B_get_s()::Cdouble
> end
> else
> getfield(this, s)
> end
> end
> 
> ```

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [August 7, 2023, 9:02pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/2 "2023-08-07T21:02:06Z")

</div>

Ok - an even simpler one. This time, the class just has a double. There is a method on the class that returns that double. This seems to work.

> **This is the C++ "library"**
>
> ```cpp
> // this is "stuff.h"
> class MainApp {
> private:
> double g;
> 
> public:
> double get_g() const;
> explicit MainApp(double g);
> };
> 
> ```
> 
> ```cpp
> #include "stuff.h"
> // this is "stuff.cpp"
> 
> MainApp::MainApp(double g) : g(g) {}
> double MainApp::get_g() const { return g; }
> 
> ```

> **This is the C wrapper**
>
> ```cpp
> #pragma once
> // this is "wrap_stuff.h"
> #ifdef __cplusplus
> #include "stuff.h"
> #endif
> 
> typedef struct H_mainapp H_mainapp;
> 
> #ifdef __cplusplus
> extern "C" {
> #endif
> 
> H_mainapp *MainApp_create(double c);
> void MainApp_destroy(H_mainapp *m);
> double MainApp_get_g(H_mainapp *m);
> 
> #ifdef __cplusplus
> } // extern
> 
> ```
> 
> ```cpp
> 
> #include "wrap_stuff.h"
> #include <new>
> // This is "wrap_stuff.cpp"
> H_mainapp *MainApp_create(double g) {
> return reinterpret_cast<H_mainapp *>(new (std::nothrow) MainApp(g));
> }
> 
> double MainApp_get_g(H_mainapp *m) {
> MainApp *p = reinterpret_cast<MainApp *>(m);
> return p->get_g();
> }
> 
> void MainApp_destroy(H_mainapp *m) {
> MainApp *p = reinterpret_cast<MainApp *>(m);
> delete p;
> }
> 
> ```

And this is the Julia code that uses the wrapper.

```julia

mutable struct MainApp
    p::Ptr{Cvoid}

    function MainApp(a)
        obj = @ccall "libstuff_wrapper.so".MainApp_create(a::Cdouble)::Ptr{Cvoid}
        if obj != C_NULL
            g = new(obj)
            finalizer(x -> ccall((:MainApp_destroy, "libstuff_wrapper.so"), Cvoid, (Ptr{Cvoid},), x.p), g)
        else
            error("Can't create MainApp");
        end
    end
end

propertynames(::MainApp, private=false) = (:get_g,)

function Base.getproperty(this::MainApp, s::Symbol)
    if s == :get_g
        function()
            @ccall "libstuff_wrapper.so".MainApp_get_g(this.p::Ptr{Cvoid})::Cdouble
        end
    else
        getfield(this, s)
    end
end

```

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [August 7, 2023, 9:30pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/3 "2023-08-07T21:30:58Z")

</div>

> [@frylock](#):
>
> I wrote a C wrapper around the C++ library

Why did you do that? Did you consider:

> **[GitHub - jw3126/CxxCall.jl: Simple stupid C++ interop](https://github.com/jw3126/CxxCall.jl)**
>
> Simple stupid C++ interop. Contribute to jw3126/CxxCall.jl development by creating an account on GitHub.

(or CxxInterface.jl directly; "CxxWrap.jl that “is probably the most mature option”)?

I realize it’s common to make a C interface, since C++ is famously hard to call from other languages. And that is of course valid if you want to call from a C application (only), i.e. as you’re doing “that uses the wrapper works as expected”, but was that just for a test case? I’m just trying to be helpful, I discovered CxxCall.jl recently and a YouTube video stating it’s the easiest way.

[If you want your C++ code callable from many languages, e.g. Python (and or C itself), then it’s valuable to have the wrapper on the C side, i.e. a neutral language. Python people might use Boost Python (or some other alternative), and I’m curious canyou use such wrappers directly from Julia without Python’s involvement? And same, can you use C++ code made to work for R, directly from Julia without R or RCall.jl?]

Even if you make your code seemingly usable only with Julia, somehow, e.g. the wrapper on the Julia side, then that doesn’t strictly rule out using the C++ code from e.g. Python, see JuliaCall/PythonCall.jl.

EDIT: @frylock FYI also found [GitHub - grasph/wrapit: Automatization of C++--Julia wrapper generation](https://github.com/grasph/wrapit)

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [August 7, 2023, 9:38pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/4 "2023-08-07T21:38:04Z")

</div>

I have looked at a couple of the wrapper generator libraries, but what really messes up life for me is that the library that I really want to wrap throws exceptions - and that just breaks everything. I sort of figured out a way to handle the exceptions at the C layer, but my additional complication has me confused about writing a wrapper using the existing packages.

I’m just trying to distil things down to the simplest thing that has my problem in it - and that problem seems to be that getting pointers to classes that are members of another class.

I will revisit CxxWrap.jl though

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [August 7, 2023, 9:46pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/5 "2023-08-07T21:46:31Z")

</div>

Ok - I figured this out, but in doing so, I make this a poster child for automated wrapper generators: I missed some function arguments when I hand wrote the example. TL;DR the `@ccall` parts should have referenced `this.p::Ptr{Cvoid}`. I naively expected that an error would have been thrown for wrong arguments.

> **the longer version**
>
> ```julia
> --- julia_test.jl 2023-08-07 16:35:21.170275259 -0500
> +++ julia_test.jl.ori 2023-08-07 16:34:55.630275688 -0500
> @@ -15,13 +15,13 @@
> function Base.getproperty(this::MainApp, s::Symbol)
> if s == :borrowA
> function()
> - ah = @ccall "libstuff_wrapper.so".MainApp_borrow_A(this.p::Ptr{Cvoid})::Ptr{Cvoid}
> + ah = @ccall "libstuff_wrapper.so".MainApp_borrow_A()::Ptr{Cvoid}
> @show ah
> A(ah)
> end
> elseif s == :borrowB
> function()
> - B(@ccall "libstuff_wrapper.so".MainApp_borrow_B(this.p::Ptr{Cvoid})::Ptr{Cvoid})
> + B(@ccall "libstuff_wrapper.so".MainApp_borrow_B()::Ptr{Cvoid})
> end
> else
> getfield(this, s)
> @@ -42,7 +42,7 @@
> @show s
> if s == :get_id
> function()
> - @ccall "libstuff_wrapper.so".A_get_id(this.p::Ptr{Cvoid})::Cint
> + @ccall "libstuff_wrapper.so".A_get_id()::Cint
> end
> else
> getfield(this, s)
> @@ -62,7 +62,7 @@
> function Base.getproperty(this::B, s::Symbol)
> if s == :get_s
> function()
> - @ccall "libstuff_wrapper.so".B_get_s(this.p::Ptr{Cvoid})::Cdouble
> + @ccall "libstuff_wrapper.so".B_get_s()::Cdouble
> end
> else
> getfield(this, s)
> 
> ```

---

<div class="post-metadata">

### Author: ![Freddy\_Chua](https://avatars.discourse-cdn.com/v4/letter/f/bc8723/32.png) [@Freddy\_Chua](https://discourse.julialang.org/u/Freddy_Chua)
#### Post date: [September 11, 2023, 5:44pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/6 "2023-09-11T17:44:33Z")

</div>

@frylock Do the structs need to be mutable?

---

<div class="post-metadata">

### Author: ![Freddy\_Chua](https://avatars.discourse-cdn.com/v4/letter/f/bc8723/32.png) [@Freddy\_Chua](https://discourse.julialang.org/u/Freddy_Chua)
#### Post date: [September 11, 2023, 5:47pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/7 "2023-09-11T17:47:32Z")

</div>

Oh, it has to be mutable to be finalized…

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [September 11, 2023, 5:51pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/8 "2023-09-11T17:51:44Z")

</div>

I wasn’t exactly sure why - but they didn’t work without making them mutable.

---

<div class="post-metadata">

### Author: ![Freddy\_Chua](https://avatars.discourse-cdn.com/v4/letter/f/bc8723/32.png) [@Freddy\_Chua](https://discourse.julialang.org/u/Freddy_Chua)
#### Post date: [September 11, 2023, 6:07pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/9 "2023-09-11T18:07:24Z")

</div>

Btw, did you eventually determine that CxxWrap is a better choice? I find it unnecessarily complex and non-native.

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [September 11, 2023, 6:14pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/10 "2023-09-11T18:14:52Z")

</div>

I never revisited it, and I agree that CxxWrap seemed very complex - we had a solution that sort of worked (i.e., the above) and pushed off any upgrades to it until later. That might be long while …

There was a suggestion to use “wrapit” above, based on the language mix in GitHub, it appears to be written mostly in C++ …

---

<div class="post-metadata">

### Author: ![Freddy\_Chua](https://avatars.discourse-cdn.com/v4/letter/f/bc8723/32.png) [@Freddy\_Chua](https://discourse.julialang.org/u/Freddy_Chua)
#### Post date: [October 3, 2023, 11:00pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/11 "2023-10-03T23:00:27Z")

</div>

@frylock I have some memory leak due to this C++ wrapping. I’m certain the memory leak is happening at the Julia/C interface layer. Did you experience this too?

---

<div class="post-metadata">

### Author: ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)
#### Post date: [October 4, 2023, 12:08pm UTC](https://discourse.julialang.org/t/wrapping-c-class/102573/12 "2023-10-04T12:08:38Z")

</div>

Oh no - I hadn’t noticed, but I hadn’t checked. My application tends to run quickly and then stop … I’ll try to check it out, and if I find anything I’ll post back here.

Any chance you could post a small example somewhere that demonstrates the leak?

When I get a chance, I might try this out: [Valgrind with Julia](https://docs.julialang.org/en/v1/devdocs/valgrind/).
