# Dynamic Type in CxxWrap.jl

**URL:** https://discourse.julialang.org/t/dynamic-type-in-cxxwrap-jl/133007
**Category:** Specific Domains
**Tags:** ccall, cxx, dispatch, cxxwrap
**Created:** [October 9, 2025, 11:51am UTC](https://discourse.julialang.org/t/dynamic-type-in-cxxwrap-jl/133007 "2025-10-09T11:51:52Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![phK3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phk3/32/45646_2.png) [@phK3](https://discourse.julialang.org/u/phK3)
#### Post date: [October 9, 2025, 11:51am UTC](https://discourse.julialang.org/t/dynamic-type-in-cxxwrap-jl/133007/1 "2025-10-09T11:51:53Z")

</div>

I want to use `CxxWrap.jl` to create a Julia wrapper for a C++ library.

On the Julia side, I want to dispatch on the type of my arguments.  
But when using `CxxWrap`, the Julia side only seems to know about the _static_ return type (the one in the signature of the C++ function) and not about the _dynamic_ return type (which can be a subtype of the static return type).

**Is there a way to expose the dynamic return type to Julia?**

Here’s the simplest MWE I could come up with:

```c++
// polymorphism.cpp

#include <jlcxx/jlcxx.hpp>
#include <iostream>

struct Parent {
    virtual std::string name() const { return "Parent"; }
    virtual ~Parent() = default;
};

struct DerivedA : public Parent {
    std::string name() const override { return "DerivedA"; }
};

struct DerivedB : public Parent {
    std::string name() const override { return "DerivedB"; }
};

Parent* make_a() { return new DerivedA(); }
Parent* make_b() { return new DerivedB(); }

JLCXX_MODULE define_julia_module(jlcxx::Module& mod)
{
    mod.add_type<Parent>("Parent")
        .method("name", &Parent::name);

    mod.add_type<DerivedA>("DerivedA", jlcxx::julia_base_type<Parent>())
        .method("name", &DerivedA::name);

    mod.add_type<DerivedB>("DerivedB", jlcxx::julia_base_type<Parent>())
        .method("name", &DerivedB::name);

    mod.method("make_a", &make_a);
    mod.method("make_b", &make_b);
}

```

and on the Julia side

```julia
# test.jl

using CxxWrap

@wrapmodule(() -> joinpath(@ __DIR__ , "build", "libpolymorphism"))

function __init__ ()
    @initcxx
end

a = make_a()
b = make_b() 

println("Type of a: ", typeof(a)) # CxxPtr{Parent}
println("Type of b: ", typeof(b)) # CxxPtr{Parent}

println("Name from a.name(): ", name(a)) # DerivedA
println("Name from b.name(): ", name(b)) # DerivedB

```

Ideally, I want `typeof(a)` to print `CxxPtr{DerivedA}` (and similarly for `b`).

Here’s the cmake file, in case you want to build the MWE yourself:

```julia-auto
cmake_minimum_required(VERSION 3.10)
project(CxxWrapPolymorphicMWE)

find_package(JlCxx REQUIRED)

add_library(polymorphism SHARED src/polymorphism.cpp)
target_link_libraries(polymorphism PRIVATE JlCxx::cxxwrap_julia)

```

---

<div class="post-metadata">

### Author: ![phK3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phk3/32/45646_2.png) [@phK3](https://discourse.julialang.org/u/phK3)
#### Post date: [October 20, 2025, 9:56am UTC](https://discourse.julialang.org/t/dynamic-type-in-cxxwrap-jl/133007/2 "2025-10-20T09:56:31Z")

</div>

@barche helped me over at [GitHub](https://github.com/JuliaInterop/CxxWrap.jl/issues/493) with this issue, the solution is as follows:

You have to define the type hierarchy in the `jlcxx` namespace, so add

```c++
namespace jlcxx
{
  template<> struct SuperType<DerivedA> { typedef Parent type; };
  template<> struct SuperType<DerivedB> { typedef Parent type; };
}

```

to the `C++` code.

Then you can just try to manually convert the return value to the corresponding dynamic type on the julia side:

```julia
a = make_a()
# CxxPtr{Parent}(Ptr{Parent}(0x00007f7ac6869310))

# works as expected
a2 = convert(CxxPtr{DerivedA}, a)
# CxxPtr{DerivedA}(Ptr{DerivedA}(0x00007f7ac6869310))

# conversion to the wrong type fails and returns a null pointer
ab = convert(CxxPtr{DerivedB}, a)
# CxxPtr{DerivedB}(Ptr{DerivedB}(0x0000000000000000))

ab == C_NULL
# true

```
