'Retrieving a stack-allocated value from a C++/CXX.rs-managed binding
I am calling out to a C++ library from inside of Rust. I am using the CXX binding generator along with some C++ "glue" code. The idea is that I initialize an object (easy enough) and then call a method to get an "enumerator" data type. It doesn't matter that it's an enumerator but it is important to note the enumerator is passed back as a stack-allocated piece of data.
The C++ library has this signature:
TautomerEnumeratorResult RDKit::MolStandardize::TautomerEnumerator::enumerate ( const ROMol & mol ) const
So you create a TautomerEnumerator instance, pass in a Mol reference, and the method gives you a stack TautomerEnumeratorResult.
The C++ wrapper side of the CXX bridge looks like:
#include "rust/cxx.h"
#include "GraphMol/GraphMol.h"
#include "GraphMol/SmilesParse/SmilesParse.h"
#include "GraphMol/SmilesParse/SmilesWrite.h"
#include "DataStructs/ExplicitBitVect.h"
#include "GraphMol/Fingerprints/Fingerprints.h"
#include "GraphMol/MolStandardize/Tautomer.h"
namespace RDKit {
using ExplicitBitVect = ::ExplicitBitVect;
using TautomerEnumerator = MolStandardize::TautomerEnumerator;
using TautomerEnumeratorResult = MolStandardize::TautomerEnumeratorResult;
TautomerEnumeratorResult enumerate_tautomer(TautomerEnumerator *enumerator, std::shared_ptr<ROMol> mol) {
return enumerator->enumerate(*mol);
}
}
which is fine. the Rust side of the CXX bridge looks like:
#[cxx::bridge(namespace = "RDKit")]
pub mod ffi {
unsafe extern "C++" {
include!("wrapper/include/rdmol.h");
pub type TautomerEnumerator;
pub type TautomerEnumeratorResult;
pub unsafe fn tautomer_enumerator() -> *mut TautomerEnumerator;
pub unsafe fn enumerate_tautomer(mol: SharedPtr<ROMol>) -> TautomerEnumeratorResult;
}
}
which blows at compile time with:
error[cxxbridge]: returning opaque C++ type by value is not supported
┌─ src/cxx/bridge/mol_standardize.rs:9:68
│
9 │ pub unsafe fn enumerate_tautomer(mol: SharedPtr<ROMol>) -> TautomerEnumeratorResult;
│ ^^^^^^^^^^^^^^^^^^^^^^^^ returning opaque C++ type by value is not supported
│
= hint: wrap it in a UniquePtr<> or SharedPtr<>
But since it's a stack allocated variable I can't return it. Is there a zero cost way of sharing TautomerEnumeratorResult with Rust over the stack? How can I make the variable "non opaque" when it's a class and not a struct?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
