2015-06-09 3 views
5

Я пытаюсь связать с простым C Lib на окнах против библиотеки Rustссылок на статический Lib скомпилированного с MSVC

Моего Lib является .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) ->() ; 
} 

Linki нг не удается, давая ошибку с одним из символов данных

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 [email protected][email protected]@[email protected]: symbol not found 

Библиотека построена на MSVC2013 как простой статический Lib. Строка «hello world» находится в разделе данных, поэтому я не ожидал, что она вызовет ошибку ссылки. Существуют ли какие-то конкретные настройки, о которых мне нужно знать при связывании с библиотеками C на окнах?

Btw это 32-разрядная библиотека MSVC.

+0

Что делать, если вы пытаетесь построить DLL с GCC? –

+0

ржавчина получила поддержку msvc несколько дней назад, но я не думаю, что есть какие-то msvc-nightlies, и я не знаю, как далеко продвинулась эта поддержка. Вы можете попытаться создать свой собственный mvsc-rustc, вызвав './Configure' с' --target x86_64-pc-windows-msvc', сообщите нам, как все прошло! связанный с PR: https://github.com/rust-lang/rust/pull/25848 –

ответ

9

Хорошо, несколько вещей. Прежде всего, нет такой вещи, как «статическая DLL»: DLL - это динамически связанная библиотека.

Во-вторых, Rust использует инструментарий MinGW и время выполнения. Смешивание времени работы MSVC и MinGW может вызвать странные вещи, поэтому, вероятно, лучше всего избежать, если это вообще возможно. Rust только недавно приземлился очень рано поддержка для строительства с использованием среды MSVC.

Однако, вы можете получить этот конкретный пример работать, по-видимому, без каких-либо побочных эффектов. Вам просто нужно изменить несколько вещей:

  • Вам необходимо использовать динамическую библиотеку; я понимаю, что это делает плохое взаимодействие немного менее вероятным.

  • Вы должны фактически компилировать say_hello с C связью, а не C++ сцепления. Вы сделали это в заголовке, но не в исходном файле.

  • Необходимо публично экспортировать say_hello из библиотеки.

Таким образом:

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.

+0

Я имел в виду статический lib, а не dll. К сожалению, наши «корпоративные» библиотеки написаны с использованием MSVC, поэтому я не могу изменить их. Я приведу приведенный выше вопрос: – Ronnie

+2

@Ronnie, если вы имеете в виду статическую библиотеку, а не DLL, вам, вероятно, следует обновить свой вопрос, чтобы это отразить. В настоящее время он несколько раз утверждает, что это DLL. –

Смежные вопросы