链接到使用MSVC编译的静态库 [英] Linking to a static lib compiled with MSVC
问题描述
我正在尝试在Windows上针对Rust库链接一个简单的C库
I'm trying to link with a simple C lib on windows against Rust library
我的库是.h
extern "C" {
void say_hello(const char* s);
}
.cpp
#include <stdio.h>
void say_hello(const char* s) {
printf("hello world");
}
我的Rust文件
#[link(name="CDbax", kind="static")]
extern "C" {
fn say_hello(s: *const libc::c_char) -> () ;
}
由于数据符号之一出现错误,链接失败
Linking fails by giving an error with one of the data symbols
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
该库基于MSVC2013 a构建一个简单的静态库。字符串 hello world在数据部分中,因此我不希望它引起链接错误。在Windows上与C库链接时是否需要了解一些特定设置?
The library is build on MSVC2013 as a simple static lib. The string "hello world" is in the data section, so I wouldn't expect it to cause a link error. Are there some specific settings I need to be aware about when linking with C libraries on windows?
顺便说一下,它是32位MSVC库。
Btw it's 32bit MSVC lib.
推荐答案
好,几件事。首先,没有静态DLL这样的东西:DLL是动态链接库。
Ok, a few things. First of all, there's no such thing as a "static DLL": a DLL is a dynamically linked library.
第二,Rust使用MinGW工具链和运行时。将MSVC和MinGW运行时混合使用可能会导致奇怪的事情发生,因此,如果可能的话,最好避免这样做。 Rust直到最近才很早获得对使用MSVC运行时进行构建的支持。
Secondly, Rust uses the MinGW toolchain and runtime. Mixing MSVC and MinGW runtimes can cause odd things to happen, so it's probably best avoided if at all possible. Rust has only recently landed very early support for building using the MSVC runtime.
但是,您可以 specific 示例有效,显然没有任何不良影响。您只需要更改一些内容即可:
However, you can get this specific example to work, apparently without any ill effects. You just need to change a few things:
-
您需要使用动态库;我的理解是,这样可以减少不良互动的可能性。
You need to use a dynamic library; my understanding is that this makes bad interactions a little less likely.
您需要实际上编译 say_hello
具有 C
链接,而不是 C ++
链接。您是在标头中执行此操作,而不是在源文件中执行此操作。
You need to actually compile say_hello
with C
linkage, not C++
linkage. You did this in the header, but not in the source file.
您需要公开导出 say_hello
You need to publicly export say_hello
from the library.
因此:
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
在我的计算机上,这会生成 hello.exe
和 hello.dll
;运行时, hello.exe
打印出 hello world
。
On my machine, this produces hello.exe
and hello.dll
; when run, hello.exe
prints out hello world
.
这篇关于链接到使用MSVC编译的静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!