I am trying to run some rust code in c++ as practice but I don't know why I am getting weird values here:
cmake_minimum_required(VERSION 3.11.0)
project(4Gewinnt VERSION 0.2.1)
include(CTest)
enable_testing()
add_library(ai_lib SHARED
src/mirror_ai.cpp
)
# Add the Rust project as an external dependency
include(ExternalProject)
ExternalProject_Add(
rust_example
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rust_example"
BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rust_example"
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build --release
INSTALL_COMMAND ""
BUILD_BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/rust_example/target/release/librust_example.so" # Adjust the library name if needed
)
# Specify the C++ executable target
add_executable(VierGewinnt
src/main.cpp
src/base_entity.cpp
src/board.cpp
src/color.cpp
src/difficulty.cpp
src/easy_ai.cpp
src/game.cpp
src/hard_ai.cpp
src/medium_ai.cpp
src/player.cpp
)
target_link_libraries(VierGewinnt PRIVATE ai_lib)
# Add a custom command to build the Rust project
add_custom_command(TARGET VierGewinnt POST_BUILD
COMMAND cargo build --release
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/rust_example"
COMMENT "Building Rust project"
)
# Link against the Rust library
add_dependencies(VierGewinnt rust_example)
target_link_libraries(VierGewinnt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/rust_example/target/release/librust_example.so") # Adjust the library name if needed
# Include directories
target_include_directories(VierGewinnt PRIVATE
include
lib
"${CMAKE_CURRENT_SOURCE_DIR}/rust_example/include"
)
target_compile_features(VierGewinnt PUBLIC cxx_std_20)
target_compile_options(VierGewinnt PUBLIC -Wall -pedantic -Wextra)
rust.hpp
#pragma once
#include "board.hpp"
extern "C" {
Column rust_main(Board board, int length);
}
medium_ai.cpp
#include "medium_ai.hpp"
#include "rust.hpp"
#include <iostream>
Column MediumAI::choose_slot(const Board &board) {
int length = board.columns();
std::cout << "[cpp] board.columns: " << length << std::endl;
Column result = rust_main(board, length);
return result;
}
lib.rs
use autocxx::prelude::*;
use rand::Rng;
include_cpp! {
#include "board.hpp"
#include "column.hpp"
safety!(unsafe_ffi)
generate!("Board")
generate!("Column")
}
#[no_mangle]
pub extern "C" fn rust_main(board: ffi::Board, length: i32) -> UniquePtr<ffi::Column> {
println!(
"[rust] board.columns: {}, length: {}",
board.columns(),
length
); // --> both random and different
let mut rand_slot: usize;
let mut rng = rand::thread_rng();
loop {
rand_slot = rng.gen_range(0..=board.columns());
println!("[rust] rand_slot: {}", rand_slot);
if !board.is_full(ffi::Column::new(rand_slot).within_unique_ptr()) {
break;
}
}
let column = ffi::Column::new(rand_slot).within_unique_ptr();
column
}
in the medium_ai the cout says its 7 like it should be in the rust file they are like c++ when you print a c++ value when they are initialized but don't have a value.
can somebody tell me what I am doing wrong?
Make board
a reference in the signature of rust_main
in lib.rs, i.e. change
pub extern "C" fn rust_main(board: ffi::Board, length: i32) -> UniquePtr<ffi::Column>
to
pub extern "C" fn rust_main(board: &ffi::Board, length: i32) -> UniquePtr<ffi::Column>