I wanted to eddit the wiki extension page directly, but: "Registraion of new accounts for the Community Wiki has been temporarily suspended. We apologize for the inconvenience."
And i didn't find much on the Topic when i was looking, so i wanted to Post it here to maybe help people who want to use Rust to make a DLL for Arma3:
Disclaimer it's only working for 64bits Arma3, but it should be easy to make it work for Arma3 32bits
Here is the code:
> lib.rs
#![feature(rustc_private)]
#![feature(libc)]
extern crate libc;
use libc::{size_t, strncpy};
use std::ffi::{CStr, CString};
use std::os::raw::*;
use std::str;
/// # Safety
// Called by Arma: STRING callExtension STRING
// __declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function);
// This function link our DLL to arma, thus it cannot be Safe (raw pointers, etc...)
// https://community.bistudio.com/wiki/Extensions
#[allow(non_snake_case)]
#[no_mangle]
#[export_name = "RVExtension"]
pub unsafe extern "stdcall" fn RVExtension(
output: *mut c_char,
outputSize: size_t,
function: *const c_char,
) {
// get str from arma
let utf8_arr: &[u8] = CStr::from_ptr(function).to_bytes();
let request: &str = str::from_utf8(utf8_arr).unwrap();
// send str to arma
let response = CString::new(request).unwrap().into_raw();
strncpy(output, response, outputSize - 1);
}
/// # Safety
// Called by Engine on extension load
// __attribute__((dllexport)) void RVExtensionVersion(char *output, int outputSize);
// This function link our DLL to arma, thus it cannot be Safe (raw pointers, etc...)
// https://community.bistudio.com/wiki/Extensions
#[allow(non_snake_case)]
#[no_mangle]
#[export_name = "RVExtensionVersion"]
pub unsafe extern "stdcall" fn RVExtensionVersion(output: *mut c_char, outputSize: size_t) {
let versionstr = "V0.1 DEBUG";
let response = CString::new(versionstr).unwrap().into_raw();
println!("size_t: {:#?}", outputSize);
strncpy(output, response, outputSize - 1);
}
> cargo.rs
[package]
name = "arma3singlemultiplayer"
version = "0.1.0"
authors = ["GreeFine <greefine@hotmail.fr>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
> main.rs # use to try
#![feature(rustc_private)]
#![feature(libc)]
mod lib;
use crate::lib::*;
use std::ffi::{CStr, CString};
use std::str;
fn main() {
unsafe {
test();
}
}
unsafe fn test() {
let buffer = CString::new("____________________").unwrap().into_raw();
let utf8_arr: &[u8] = CStr::from_ptr(buffer).to_bytes();
println!("buffer: [{}]", str::from_utf8(utf8_arr).unwrap());
RVExtensionVersion(buffer, utf8_arr.len() + 1);
println!("buffer result: [{}]", str::from_utf8(utf8_arr).unwrap());
}
To compile this i use the component "x86_64-pc-windows-gnu"
rustup component add rust-std-x86_64-pc-windows-msvc
And then to compile:
cargo build --lib --release --target x86_64-pc-windows-gnu