cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Using C++ classes and methods in Rust.

Open SmolPatches opened this issue 2 years ago • 1 comments

I have a header file like this,

#pragma once
#include <cstdint>
#include <fstream>
#include <vector>

#pragma pack(push,1)
struct TGAHeader {
    std::uint8_t  idlength = 0;
    std::uint8_t  colormaptype = 0;
    std::uint8_t  datatypecode = 0;
    std::uint16_t colormaporigin = 0;
    std::uint16_t colormaplength = 0;
    std::uint8_t  colormapdepth = 0;
    std::uint16_t x_origin = 0;
    std::uint16_t y_origin = 0;
    std::uint16_t width = 0;
    std::uint16_t height = 0;
    std::uint8_t  bitsperpixel = 0;
    std::uint8_t  imagedescriptor = 0;
};
#pragma pack(pop)

struct TGAColor {
    std::uint8_t bgra[4] = {0,0,0,0};
    std::uint8_t bytespp = 4;
    std::uint8_t& operator[](const int i) { return bgra[i]; }
};

struct TGAImage {
    enum Format { GRAYSCALE=1, RGB=3, RGBA=4 };

    TGAImage() = default;
    TGAImage(const int w, const int h, const int bpp);
    bool  read_tga_file(const std::string filename);
    bool write_tga_file(const std::string filename, const bool vflip=true, const bool rle=true) const;
    void flip_horizontally();
    void flip_vertically();
    TGAColor get(const int x, const int y) const;
    void set(const int x, const int y, const TGAColor &c);
    int width()  const;
    int height() const;
private:
    bool   load_rle_data(std::ifstream &in);
    bool unload_rle_data(std::ofstream &out) const;

    int w = 0;
    int h = 0;
    std::uint8_t bpp = 0;
    std::vector<std::uint8_t> data = {};
};

and I am trying to use it from within Rust. Build.rs

fn main() {
    // Tell cargo to look for shared libraries in the specified directory
    println!("cargo:rustc-link-search=./tga");

    // Tell cargo to tell rustc to link the system bzip2
    // shared library.
    println!("cargo:rustc-link-lib=tgaimage");

    // Tell cargo to invalidate the built crate whenever the wrapper changes
    println!("cargo:rerun-if-changed=tgaimage.h");

    cxx_build::bridge("src/main.rs")  // returns a cc::Build
        .file("tga/tgaimage.cpp")
        .flag_if_supported("-std=c++20")
        .flag_if_supported("-fno-inline-functions")
        .include("tga")
        .compile("tgaimage");
}

With a rust bridge like in src/main.rs as follows,

use cxx::let_cxx_string;
mod tgaimage {
    #[cxx::bridge]
    pub mod ffi {
        unsafe extern "C++" {
            include!("tgaimage.h");
            type TGAImage;
            type TGAHeader;
            type TGAColor;
            pub fn read_tga_file(self:&TGAImage,filename:&CxxString) -> bool;
        }
    }
}
use tgaimage::ffi::*;
pub(crate) fn main() {
    let x: tgaimage::ffi::TGAImage;
}

When I run cargo b or cargo r The output I get when building is below,

warning: /Users/r3b/Documents/Projects/software_renderer/target/debug/build/software_renderer-9a5add0671fa0bbb/out/cxxbridge/sources/software_renderer/src/main.rs.cc:10:22: error: cannot initialize a variable of type 'bool (TGAImage::*)(const ::std::string &) const' with an rvalue of type 'bool (TGAImage::*)(const std::string)': type mismatch at 1st parameter ('const ::std::string &' (aka 'const basic_string<char, char_traits<char>, allocator<char>> &') vs 'const std::string' (aka 'const basic_string<char, char_traits<char>, allocator<char>>'))
warning:   bool (::TGAImage::*read_tga_file$)(::std::string const &) const = &::TGAImage::read_tga_file;
warning:                      ^                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: 1 error generated.

error: failed to run custom build command for `software_renderer v0.1.0 (/Users/r3b/Documents/Projects/software_renderer)`

Caused by:
  process didn't exit successfully: `/Users/r3b/Documents/Projects/software_renderer/target/debug/build/software_renderer-5e0b03cc1cb43eb2/build-script-build` (exit status: 1)

What is the proper way to build a bridge to use a cstring in rust? Am I using CxxString incorrectly?

SmolPatches avatar Sep 02 '23 05:09 SmolPatches

I have the same question. Any luck @SmolPatches?

metasim avatar Mar 19 '24 18:03 metasim

Sorry that no one was able to provide guidance here. If this is still an issue, you could try taking this question to any of the resources shown in https://www.rust-lang.org/community.

dtolnay avatar Sep 09 '25 23:09 dtolnay