baldrs
baldrs

Reputation: 2161

How to dereference C/C++ void * to struct or callback in Rust?

I want to write an AI for an old game, in Rust. AI's for this game are libraries, in its Linux port it's just an .so file exporting:

extern "C" void client(int Command, int Player, void *Data);

void *Data can be either struct (depends on Command) or this function:

typedef int TServerCall(int Command, int Player, int Subject, void *Data);

In C++, AI code casts it depending on command, to a struct of known size or callback, like:

typedef int __stdcall TServerCall(int Command, int Player, int Subject, void *Data);

or to struct:

// where G is a extern TNewGameData G;

G = *(TNewGameData *) Data;

And then I can access fields of G or other structs, or arrays.

Question:

How do I cast data in form of void * to struct or function in Rust?

Upvotes: 2

Views: 1425

Answers (1)

Alice Ryhl
Alice Ryhl

Reputation: 4219

You can cast raw pointers in Rust.

use libc::{c_void, c_int};

#[repr(C)]
struct TNewGameData {
    // the fields go here
}

#[no_mangle]
pub extern "C" fn client(command: c_int, player: c_int, data: *mut c_void) {
    // Cast raw pointer to the right type.
    let game_data_ptr = data as *mut TNewGameData;
    // Convert to Rust reference.
    let game_data = unsafe { &mut *data };
}

Upvotes: 3

Related Questions