rust-lang / rust-lang/rust-bindgen

[feature] Add support for reverse bindgen function implementation

Open
#3,310 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Problem

The goal is to have c headers be the source of truth and then have bindgen generate function signatures that can be implemented by rust code.

the following code is generated by this header

/**
 * @brief Set the last error message
 * @param message Error message
 */
void error_set_last_message(const char* message);

/**
 * @brief Get the last error message
 * @return Last error message or NULL if no error occurred
 */
const char* error_last_message();
unsafe extern "C" {
    #[doc = " @brief Set the last error message\n @param message Error message"]
    pub fn error_set_last_message(message: *const ::std::os::raw::c_char);
}
unsafe extern "C" {
    #[doc = " @brief Get the last error message\n @return Last error message or NULL if no error occurred"]
    pub fn error_last_message() -> *const ::std::os::raw::c_char;
}

I would like bindgen to generate something like the following

pub trait error_api {
    #[doc = " @brief Set the last error message\n @param message Error message"]
    unsafe extern "C" fn error_set_last_message(message: *const ::std::os::raw::c_char);
    #[doc = " @brief Get the last error message\n @return Last error message or NULL if no error occurred"]
    unsafe extern "C" fn error_last_message() -> *const ::std::os::raw::c_char;
}

With some sort of builder setting like

let bindings = bindgen::builder()
    .function_impl_trait("error_.*", "error_api");

Then using this would be like

pub struct Extern;

impl error_api for Extern {
    #[unsafe(no_mangle)]
    unsafe extern "C" fn error_set_last_message(message: *const ::std::os::raw::c_char) {
        ...
    }

    #[unsafe(no_mangle)]
    unsafe extern "C" fn error_last_message() -> *const ::std::os::raw::c_char {
        ...
    }
}

Motivation

A lot of code today is written in c++ / c with a public c-api that is exported so that other languages / customers can interact with the underlying code without having its source. In an effort to move more code over to rust having some way of using the c headers as a source of truth would make it easier to incrementally port legacy code bases over to rust.

Alternative solutions

  1. Using a tool like cbindgen to generate the header files from the rust code. While this solution is good i would still prefer to have the headers be the source of truth for the definitions of the functions.

  2. Bindgen can be extended to generate something like the following instead of the extern "C" blocks.

#[doc = " @brief Set the last error message\n @param message Error message"]
#[repr(transparent)]
pub struct error_set_last_message(pub unsafe extern "C" fn(message: *const ::std::os::raw::c_char));

#[doc = " @brief Get the last error message\n @return Last error message or NULL if no error occurred"]
#[repr(transparent)]
pub struct error_last_message(pub unsafe extern "C" fn() -> *const ::std::os::raw::c_char);

And then its up to the library author to implement and expose these functions and can use these types to validate they are the same as the header. Also has the advantage of allowing bindgen to be used with dlopen


Related https://github.com/rust-lang/rust/issues/58493

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No source file or test is named in the issue. Begin by locating bindgen's function-generation entry point and existing builder options, then determine how the proposed trait output should be represented and tested; done means the requested builder setting generates implementable Rust traits for matching C functions.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.