cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Unable to pass `extern "C" fn()` as a argument: cxx ignores `extern "C"`

Open danakj opened this issue 3 years ago • 1 comments

I started at https://github.com/dtolnay/cxx/issues/895 since I want to pass a function pointer in C++, but I see this is different.

I want to pass an extern "C" fn() as a function argument to C++ (as suggested in #895) but cxx produces a rust::Fn from it instead of a void (*)(), so I am unable to get to the actual function pointer. The only workaround I can see at the moment is to avoid cxx entirely and write my own

extern {
  fn takes_ptr(ptr: extern "C" fn());
}

Here's the cxx::bridge block I want to write but can't:

pub mod internals {
    #[cxx::bridge(namespace=base::test::ffi)]
    pub mod ffi {
        unsafe extern "C++" {
            include!("base/test/rust_gtest_interop.h");
            unsafe fn rust_add_test2(func: extern "C" fn());
        }
    }
}

Calling rust_add_test2() with an extern "C" fn produces an error since cxx ignored the extern "C":

    |
228 |     internals::ffi::rust_add_test2(c_func);
    |                                    ^^^^^^ expected "Rust" fn, found "C" fn
    |

And here's the .cc it produces:

void base$test$ffi$cxxbridge1$rust_add_test2(::rust::Fn<void()> func) noexcept {
  void (*rust_add_test2$)(::rust::Fn<void()>) = ::base::test::ffi::rust_add_test2;
  rust_add_test2$(func);
}

danakj avatar Feb 11 '22 16:02 danakj

I'm having this same issue. Did you ever figure it out, or did you do the ffi directly without cxx?

Edit: Nevermind, this works fine, a bit cumbersome, but works just fine.

dingari avatar Feb 02 '23 10:02 dingari