Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@cfunction for function taking binded class within c++ #460

Open
k12Sergey opened this issue Dec 4, 2024 · 6 comments
Open

@cfunction for function taking binded class within c++ #460

k12Sergey opened this issue Dec 4, 2024 · 6 comments

Comments

@k12Sergey
Copy link

k12Sergey commented Dec 4, 2024

Hi.
Sorry for silly question, but how to use @cfunction in the foolowing case:
Suppose we bind class:

types.add_type<DataBase>("Database")
   .method("GetProperty", &DataBase::getProperty);

and write julia function which take this class:

function Eg(db::CppTypes.Database, mat::Cint)
    return GetProperty(db, mat)
end

and try to get cfunction pointer on this function from c++:

auto *eg = (double (*)(DataBase *, int)) jl_unbox_voidpointer(jl_eval_string("@cfunction(Eg, Cdouble, (Ptr{Cvoid}, Cint))")); 

Pointer exist, but call this is trow an exception.

where im wrong?

Binded classes wrapped on julia side

mutable struct WorldAllocated <: World
  cpp_object::Ptr{Cvoid}
end

Thanks

@k12Sergey
Copy link
Author

Posibly i should change julia signature

function Eg(db::Ptr{Cvoid}, mat::Cint)
    # convert void* to CppTypes.Database ?
    return GetProperty(db, mat)
end

@barche
Copy link
Collaborator

barche commented Dec 6, 2024

Hi,

With cxxWrap I recommend making a function that accepts a SafeCFunction like this:
https://github.com/JuliaInterop/libcxxwrap-julia/blob/d4192fe3ea20829bd399d812863abd8303f9bcab/examples/functions.cpp#L243

The pointer is best generated in Julia, as here in this example:

c_func = @safe_cfunction(testf, Float64, (Float64,Float64))

@k12Sergey
Copy link
Author

k12Sergey commented Dec 6, 2024

Sorry, i still dont get which type should be in c++ signature for binded struct. SafeCFunction know how to handle custom structs?
@safe_cfunction still need to cast into function (which isnt worked)

Is it corect way to get SafeCFucntion from julia?

jlcxx::SafeCFunction *f_data = (jlcxx::SafeCFunction *) jl_unbox_voidpointer(jl_eval_string("@safe_cfunction(testf, Cfloat, (Cfloat, Cfloat))"));

auto f = jlcxx::make_function_pointer<float(float, float)>(*f_data);

This code crash when make_function with what(): Incorrect datatype for cfunction return type, expected Float32 but got Const

@k12Sergey
Copy link
Author

k12Sergey commented Dec 6, 2024

I try out to modify example from doc. (original one work correctly)

function Test(eg::CppTypes.Database) :: Cvoid
    println("im test function")
end    
ptr = @safe_cfunction(Test, Cvoid, (Main.CppTypes.DatabaseAllocated,))
println(typeof(ptr))

test_safe_cfunction(ptr)

with the following test_safe_cfunction:

 types.method("test_safe_cfunction", [](jlcxx::SafeCFunction f_data) {
    auto *f = jlcxx::make_function_pointer<void(DataBase* )>(f_data);
    std::cout << f << std::endl;
 });

and it just stop execution, nothing we printed out

@k12Sergey
Copy link
Author

Its not obvious how to get jlcxx::SafeCFunction and how to cast it to function with user binded argument.
Is it possible or wrapping work only one way and global variables on julia side should be used? (they very slow and should be const dont check if const will work correctly)

@barche
Copy link
Collaborator

barche commented Dec 10, 2024

I think it should work like this:

function Test(eg::CxxRef{CppTypes.Database}) :: Cvoid
    println("im test function")
end    
ptr = @safe_cfunction(Test, Cvoid, (CxxRef{CppTypes.Database},))
println(typeof(ptr))

test_safe_cfunction(ptr)
 types.method("test_safe_cfunction", [](jlcxx::SafeCFunction f_data) {
    auto *f = jlcxx::make_function_pointer<void(DataBase&)>(f_data);
    std::cout << f << std::endl;
 });

Or if you prefer pointers you can use CxxPtr{Database}. The key is that the types passed to safe_cfunction should all map directly to C types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants