Linking to static lib compiled using MSVC

I am trying to link to a simple C lib on windows vs Rust library

My library is.h

extern "C" { void say_hello(const char* s); } 

.cpp

 #include <stdio.h> void say_hello(const char* s) { printf("hello world"); } 

My Rust File

 #[link(name="CDbax", kind="static")] extern "C" { fn say_hello(s: *const libc::c_char) -> () ; } 

Binding fails, causing an error with one of the data characters

 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:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.o" "-o" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.dll" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.metadata.o" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libstd-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libcollections-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\librustc_unicode-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\librand-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\liballoc-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\liblibc-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libcore-11582ce5.rlib" "-L" "e:\Rust\DBTools\DBAnalytics\target\debug" "-L" "e:\Rust\DBTools\DBAnalytics\target\debug\deps" "-L" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib" "-L" "e:\Rust\DBTools\DBAnalytics\.rust\bin\i686-pc-windows-gnu" "-L" "e:\Rust\DBTools\DBAnalytics\bin\i686-pc-windows-gnu" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "CDbax" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-l" "ws2_32" "-l" "userenv" "-l" "advapi32" "-shared" "-l" "compiler-rt" note: Warning: corrupt .drectve at end of def file Cannot export ??_C@ _0M@LACCCNMM @ hello?5world?$AA@ : symbol not found 

The library is built on MSVC2013 as a simple static library. The string "hello world" is in the data section, so I did not expect it to cause a link error. Are there any specific settings that I need to know about when linking to C libraries on windows?

Btw it 32bit MSVC lib.

+5
source share
1 answer

Ok, a few things. Firstly, there is no such thing as a “static DLL”: a DLL is a dynamically linked library.

Secondly, Rust uses the MinGW toolchain and runtime. Mixing MSVC and MinGW can lead to odd things, so it's probably best avoided if at all possible. Rust only recently landed on very early support for building using the MSVC runtime.

However, you can get this particular example to work, apparently without any negative consequences. You just need to change a few things:

  • You need to use a dynamic library; I understand that this makes poor interaction a little less likely.

  • You need to compile say_hello with a C link, not C++ . You did this in the header, but not in the source file.

  • You need to publicly export say_hello from the library.

In this way:

hello.rs :

 #[link(name="hello", kind="dylib")] extern { fn say_hello(); } fn main() { unsafe { say_hello(); } } 

hello.h :

 #ifndef HELLO_H #define HELLO_H extern "C" { __declspec(dllexport) void say_hello(); } #endif 

hello.cpp :

 #include <cstdio> #include "hello.h" void say_hello() { printf("hello world\n"); } 

build.cmd

 cl /LD hello.cpp rustc -L. hello.rs 

On my machine, this produces hello.exe and hello.dll ; when running hello.exe displays hello world .

+9
source

All Articles