链接到使用MSVC编译的静态库 [英] Linking to a static lib compiled with MSVC

查看:332
本文介绍了链接到使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆