dtolnay / cxx

Safe interop between Rust and C++
https://cxx.rs
Apache License 2.0
5.91k stars 338 forks source link

Exposing shared constants #1051

Open str4d opened 2 years ago

str4d commented 2 years ago

I'd like to be able to expose Rust constants (for the purpose of this issue, assume only const primitives) to C++, so they are defined in a single location. For example, I'd like to write something like:

#[cxx::bridge(namespace = "blake2b")]
mod ffi {
    const PERSONALBYTES: usize = blake2b_simd::PERSONALBYTES;
}

or

#[cxx::bridge(namespace = "blake2b")]
mod ffi {
    const PERSONALBYTES;
}

const PERSONALBYTES: usize = blake2b_simd::PERSONALBYTES;

and have this be accessible from C++ as blake2b::PERSONALBYTES with type size_t.

shymega commented 1 year ago

This is something I'd like to achieve as well. I looked at your PR there on zcash/zcash#5971, @str4d - did you manage to find a workaround?

dtolnay commented 1 year ago

Probably this:

// .rs

#[cxx::bridge(namespace = "blake2b")]
mod ffi {
    extern "Rust" {
        fn get_personalbytes() -> usize;
    }
}

fn get_personalbytes() -> usize { blake2b_simd::PERSONALBYTES }
// .h

#pragma once
#include <cstddef>

namespace blake2b {
std::size_t const extern PERSONALBYTES;
}
// .cpp

#include "path/to/this.h"
#include "path/to/this.rs.h"

std::size_t const blake2b::PERSONALBYTES = get_personalbytes();

or this:

// .rs

#[no_mangle]
#[export_name = "blake2b_simd$PERSONALBYTES"]
pub static blake2b_simd_PERSONALBYTES: usize = blake2b_simd::PERSONALBYTES;
// .h

#pragma once
#include <cstddef>

std::size_t const extern blake2b_simd$PERSONALBYTES;

namespace blake2b {
std::size_t const static PERSONALBYTES = blake2b_simd$PERSONALBYTES;
}