
AutoCXX: Safely call C++ from Rust with auto generated bindings - Jarred
https://github.com/google/autocxx
======
adonese
Probably a follow up on this one[0]. Also related to cxx's[1] (mentioned in
chromium's original post[2])

[0]:
[https://news.ycombinator.com/item?id=24211691](https://news.ycombinator.com/item?id=24211691)
[1]: [https://github.com/dtolnay/cxx](https://github.com/dtolnay/cxx) [2]:
[https://www.chromium.org/Home/chromium-security/memory-
safet...](https://www.chromium.org/Home/chromium-security/memory-safety/rust-
and-c-interoperability)

------
kibwen
These libraries must contain a list of types which they consider "mostly
equivalent" between Rust and C++ in order to facilitate the bridge, e.g.
Rust's `Box` and C++'s `unique_ptr`. I would be interested in reading the
exhaustive list of the types that are considered equivalent; surely there must
be subtle semantic differences to account for.

~~~
steveklabnik
[https://github.com/dtolnay/cxx#builtin-
types](https://github.com/dtolnay/cxx#builtin-types)

~~~
AprilArcus
Result<T> -> throw/catch seems surprising and hard to walk back later. Why not
use std::expected or a work-alike, and let the caller decide whether to throw
an exception?

~~~
singron
Being a Googler project, I expected this to be a version of cxx that used
StatusOr and -fno-exceptions.

~~~
joshuamorton
autoCXX is Google-y, but cxx doesn't appear to be, and enforcing noexcept in a
general use tool seems ill-advised.

------
fluffy87
I wonder how it can auto generate safe bindings for C++.

To do that, it would essentially need to literally prove that the C++ code is
thread and memory safe, which is an open research problem at Best, and
probably impossible since it requires solving the halting problem.

If it can do that, then the actual binding generation would be the most
uninteresting part of this work.

~~~
yoshuaw
I read "safely call" as "does not require `unsafe {}` to call". Invariants
will still need to be manually upheld to ensure the C++ code will work as
expected.

~~~
simias
The problem with that is that making a function safe means that you guarantee
that these invariants are enforced. If you tag a function as safe erroneously
you basically throw Rust's safety out of the window.

Given that C++ has no explicit concept of safety it seems like it would be
hard to do that automatically as soon as pointers or references are involved.

As a quick example: if you have the following signature in C++:

    
    
        int *foo(int &a);
    

How you automatically generate safe FFI for it?

As a human doing the same task I'd have to ask myself at the very least:

\- Can the return value be NULL?

\- Can the return value alias a?

\- What's the lifetime of the returned value and who owns it?

~~~
rumanator
> If you tag a function as safe erroneously you basically throw Rust's safety
> out of the window.

You really don't. Rust checks are applied to the code written in Rust. If a
developer intentionally marked a dependency as safe then you get exactly what
you've asked for.

Sometimes it's unquestionably better to have a working system than not having
one just because a pedantic compiler complains about stuff that you can't do
nothing about.

~~~
ChrisSD
If an interface can break safe Rust (without that being an implementation bug)
then it should not be marked as safe. Breaking safety isn't about the compiler
being pedantic, it can break your real world program.

Yes this may mean you sometimes can't create a safe interface to a particular
foreign function. However all this means is that calling the function requires
an explicit unsafe block and extra care. But that 'unsafe' marker is valuable!
It's something that screams "here be dragons".

------
crb002
Why not wrap for use with dlopen()?

