2016-02-29 66 views
4

我试图写武装突袭3 DLL延伸和game docs说:如何在Rust中为ArmA 3 DLL实现RVExtension功能?

该DLL应该包含一个形式 _RVExtension的切入点@ 12,用下面的C签名:

void __stdcall RVExtension(char *output, int outputSize, const char *function); 

C++代码示例的一部分是:

// ... 

extern "C" { 
    __declspec(dllexport) void __stdcall RVExtension(
     char *output, 
     int outputSize, 
     const char *function 
    ); 
}; 

void __stdcall RVExtension(
    char *output, 
    int outputSize, 
    const char *function 
) { 
    outputSize -= 1; 
    strncpy(output,function,outputSize); 
} 

该文档也有很多其他语言的例子如:C#, D and even Pascal,但那些帮助不大,因为我没有很好地理解他们的FFI =(。

我坚持用下面的代码锈:

#[no_mangle] 
pub extern "stdcall" fn RVExtension(
    game_output: *mut c_char, 
    output_size: c_int, 
    game_input: *const c_char 
) { 
    // ... 
} 

但武装突袭拒绝调用它。

回答

5

感谢@ Shepmaster关于Dependency Walker的建议,我能够发现问题出在函数的名字中。我预计函数名称将被转换为[email protected],但事实并非如此。 RVExtension被直接输出,而ArmA无法通过名称[email protected]找到它。

这很奇怪,但似乎编译器版本可能会起作用。我尝试了〜8个不同的版本,并且能够使其仅适用于Rust每夜1.8(GNU ABI)32位。

工作代码为:

#![feature(libc)] 
extern crate libc; 

use libc::{strncpy, size_t}; 

use std::os::raw::c_char; 
use std::ffi::{CString, CStr}; 
use std::str; 

#[allow(non_snake_case)] 
#[no_mangle] 
/// copy the input to the output 
pub extern "stdcall" fn _RVExtension(
    response_ptr: *mut c_char, 
    response_size: size_t, 
    request_ptr: *const c_char, 
) { 
    // get str from arma 
    let utf8_arr: &[u8] = unsafe { CStr::from_ptr(request_ptr).to_bytes() }; 
    let request: &str = str::from_utf8(utf8_arr).unwrap(); 

    // send str to arma 
    let response: *const c_char = CString::new(request).unwrap().as_ptr(); 
    unsafe { strncpy(response_ptr, response, response_size) }; 
} 

也可以重写功能分为:

#[export_name="_RVExtension"] 
pub extern "stdcall" fn RVExtension(

其他一些生锈的编译器还可以一起工作:

#[export_name="[email protected]"] 
pub extern "stdcall" fn RVExtension(

但,例如每晚1.8(MSVC ABI)与VS 2015的32位将不允许@符号d在编译时抛出一个错误。 MSVC版本本身不会添加@12

其他编译器可能会添加@12,该函数将导出为[email protected]@12


还值得一提的是,ArmA是32位应用程序,所以它不适用于64位DLL。

+0

如何对Mingw做同样的想法?似乎它发生类似的事情(https://forums.bistudio.com/topic/193084-building-extensions-on-mingw/?p=3073069) – xbelanch

+0

对不起,我没有MinGW的经验。 – Ridim