Skip to content

Commit

Permalink
Update how_it_compares.md
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi authored Sep 2, 2023
1 parent 06ac024 commit e18d1c0
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions book/src/how_it_compares.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# How it compares to other tools?

Zngur is not the only tool in the Rust/C++ interoperability space. It's pros and cons relative to other popular tools are described
in this page.
Zngur is not the only tool in the Rust/C++ interoperability space. Its pros and cons relative to other popular tools are described
on this page.

## CXX

CXX says:

> Be aware that the design of this library is intentionally restrictive and opinionated! It isn't a goal to be powerful enough to handle arbitrary signatures in either language. Instead this project is about carving out a reasonably expressive set of functionality about which we can make useful safety guarantees today and maybe extend over time.
> Be aware that the design of this library is intentionally restrictive and opinionated! It isn't a goal to be powerful enough to handle arbitrary signatures in either language. Instead, this project is about carving out a reasonably expressive set of functionality about which we can make useful safety guarantees today and maybe extend over time.
Zngur also makes safety guarantees, but also tries to be powerful enough to handle arbitrary signatures from Rust code. And we believe
Zngur also makes safety guarantees but also tries to be powerful enough to handle arbitrary signatures from Rust code. And we believe
Rust types are expressive enough so that there is no need to support C++ types in Rust. For example, instead of defining a C++ opaque
type and using it in Rust by an `UniquePtr`, you can define the behavior of that type in a Rust normal trait, implement that trait
for your C++ type, and then convert that type into a `Box<dyn Trait>` and use it in Rust. Zngur benefits over CXX are:

- Zngur supports owning Rust variables on the C++ stack, saving some unnecessary allocations.
- CXX has a limited support for some types in the standard library, but Zngur supports almost everything (`Vec<T>`, `Vec<Vec<T>>`, `HashMap<T, T>`,
- CXX has limited support for some types in the standard library, but Zngur supports almost everything (`Vec<T>`, `Vec<Vec<T>>`, `HashMap<T, T>`,
`Box<[T]>`, `Arc<dyn T>`, ...) with almost full API.
- Zngur keeps the Rust side clean and normal, moving all glue code in the C++ side. But using CXX you will see the foreign types and glue codes
in both languages.
Expand All @@ -38,14 +38,14 @@ for your C++ type, and then convert that type into a `Box<dyn Trait>` and use it

## AutoCXX

AutoCXX is different. It also tries to be powerful enough to handle arbitrary signatures, but from C++ code. It does a nice job, but due
AutoCXX is different. It also tries to be powerful enough to handle arbitrary signatures but from C++ code. It does a nice job, but due
the fundamental difference between Rust and C++, it has several drawbacks:

- It wraps every function result that is not behind a reference in a `UniquePtr`, which has both performance and ergonomic costs.
- Every potentially mutable reference (`&mut`, `Box`, ...) should be wrapped in a `Pin`, similar to CXX.
- It has poor support for templates, though it might be temporary and an ideal AutoCXX might fix some of its problems with template.

So, an auto generated binding for a C++ library using AutoCXX is not an idiomatic and ergonomic Rust. So unless you are writing a very little
So, an auto-generated binding for a C++ library using AutoCXX is not an idiomatic and ergonomic Rust. So unless you are writing a very little
amount of Rust code, or can tolerate `UniquePtr` and `Pin` to be propagated in your Rust code, you will need to write a Rustic wrapper for
your C++ classes. This is even recommended in the AutoCXX docs:

Expand All @@ -59,8 +59,8 @@ in C++ that operate on Rust types. Using those, you should be able to create idi

Idiomatic C++ and idiomatic Rust are like night and day, so a glue code between them must exist. The difference between Zngur and AutoCXX is that
using AutoCXX that glue code will live in Rust and using Zngur it will live in C++. By writing the glue code in C++, you will become able to
construct C++ objects in stack without a macro, calling their move and copy constructors using `=` operator, and ... without hitting any major
problem in using Rust types.
construct C++ objects in the stack without a macro, calling their move and copy constructors using `=` operator, and ... without hitting any major
problems in using Rust types.

All being said, if you want to have fully auto generated bindings for both sides, nothing will prevent you from using Zngur and AutoCXX at the same
All being said, if you want to have fully auto-generated bindings for both sides, nothing will prevent you from using Zngur and AutoCXX at the same
time.

0 comments on commit e18d1c0

Please sign in to comment.