Description
Background
I wanted to expose a Rust library that would expose C-compatible API & ABI and would be used from C-like platform. What I need to do first is populate an array of structs.
Example
use std::slice;
#[repr(C)]
pub struct Item {
num: i32,
acc: i32,
}
#[no_mangle]
pub extern fn fill(arr: *mut Item, arr_size: i32) {
let arr = unsafe { slice::from_raw_parts_mut(arr, arr_size as usize) };
let mut sum = 0;
for (i, item) in arr.iter_mut().enumerate() {
item.num = (i + 1) as i32;
item.acc = {sum += item.num; sum};
}
}
Now when I try to compile that using latest Rust 1.0.0-beta5, I get linking errors:
error: linking with gcc failed: exit code: 1 note: "gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-Wl,--large-address-aware" "-shared-libgcc" "-L" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib" "-o" "C:\Projects\Personal\ALR\target\debug\ALR.dll" "C:\Projects\Personal\ALR\target\debug\ALR.o" "C:\Projects\Personal\ALR\target\debug\ALR.metadata.o" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libstd-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libcollections-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libunicode-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\librand-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\liballoc-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\liblibc-4e7c5e5c.rlib" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libcore-4e7c5e5c.rlib" "-L" "C:\Projects\Personal\ALR\target\debug" "-L" "C:\Projects\Personal\ALR\target\debug\deps" "-L" "C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib" "-L" "C:\Projects\Personal\ALR\src.rust\bin\i686-pc-windows-gnu" "-L" "C:\Projects\Personal\ALR\src\bin\i686-pc-windows-gnu" "-Wl,--whole-archive" "-Wl,-Bstatic" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-lws2_32" "-luserenv" "-shared" "-lcompiler-rt"
note:
C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libcore-4e7c5e5c.rlib(core-4e7c5e5c.o):(.text+0x3ab4): undefined reference to rust_begin_unwind'
C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libcore-4e7c5e5c.rlib(core-4e7c5e5c.o):(.eh_frame+0x5c7f): undefined reference to rust_eh_personality'
ld: C:\Rust\bin\rustlib\i686-pc-windows-gnu\lib\libcore-4e7c5e5c.rlib(core-4e7c5e5c.o): bad reloc address 0x5c7f in section `.eh_frame'
If I add empty println somewhere in the loop:
for (i, item) in arr.iter_mut().enumerate() {
println!("");
item.num = (i + 1) as i32;
item.acc = {sum += item.num; sum};
}
Linking actually works.
Unfortunately, when using the DLL in the third party platform, I'm getting stack overflow exception in the library (?!). That only happens when working with arrays though (iterating over a slice created from raw array, for example), passing a singular C struct by reference works just fine.