I am compiling a shared library (.so, .dylib, .dll
) that I need to call using C FFI from another language. The problem I'm running into is that this works for so
and dylib
files on Linux + Mac respectively, but the DLL seems to be missing functions marked extern "C"
.
This might be a mis-use of FFI in the language I'm using (Julia), but it works on both Linux + Mac. When I open up the DLL in DLL Export Viewer, I don't see the names of the exported functions either (e.g. test_fn
below)
For an MWE, I have the following lib.rs
and Cargo.toml
:
#[no_mangle]
pub extern "C" fn test_fn(tag_id_c: i32) -> i32 {
return tag_id_c;
}
[package]
name = "wincompile"
version = "0.1.0"
edition = "2021"
[dependencies]
[lib]
crate-type = ["cdylib"]
And I compile it using cargo-zigbuild
for Windows and Linux (x86_64-unknown-linux-gnu
and x86_64-pc-windows-gnu
).
I'm compiling the code inside a slightly modified form of the standard cargo-zigbuild
image via
cargo zigbuild --release --target x86_64-pc-windows-gnu
For completeness, the Julia code I'm trying to verify this with
# Called from Linux, prints a pointer indicating it found the function
lib = Libdl.dlopen("/path/to/libwincompile.so")
Libdl.dlsym(lib, :test_fn)
# Ptr{...}
# Call on Windows, throws error
lib = Libdl.dlopen("/path/to/wincompile.dll")
Libdl.dlsym(lib, :test_fn)
# ERROR: could not load symbol "test_fn"