簡體   English   中英

在Rust程序中嵌入Rust任務?

[英]Embedding Rust tasks in a C program?

從Rust程序(由rustc編譯的可執行文件)調用C庫函數運行良好,並且是Rust團隊的目標。

從C程序(由clang編譯的可執行文件)調用Rust crate函數正在處理簡單的事情,但是如果我生成一個任務,它就會崩潰。

如何使Rust任務起作用?


這是我的來源和錯誤消息。 您也可以從https://github.com/Eonil/TeachingMyselfRust下載

a.rs

#[no_mangle]
pub fn test1()
{
    let a1  =   proc()
    {
    };
    spawn(a1);
}

公元前

#include <stdio.h>

extern void test1();


int main(int argc, char** argv)
{
    test1();
    return 0;
}

構建腳本

rm -rf ./Build
mkdir ./Build

rustc a.rs --crate-type=staticlib -o ./Build/rust-stuffs.a
clang b.c ./Build/rust-stuffs.a -o Build/out

cd Build
./out

執行結果

warning: unlinked native library: System


There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.

fatal runtime error:  assertion failed: !ptr.is_null()
stack backtrace:
   1:        0x108bc7944 - rt::backtrace::imp::write::hdaa6a604147ca757g8b::v0.10
   2:        0x108b5f4aa - rt::util::abort::h3d7b16d436532c64Bmc::v0.10
   3:        0x108bc605a - rt::local_ptr::compiled::take::hb1c4b940f0aa52aea9a::v0.10
   4:        0x108b5e6ad - task::TaskBuilder::spawn::h2dcf43b5eaa6805aQhC::v0.10
   5:        0x108b5eb6d - task::spawn::hff1c6bd6cfded263NjC::v0.10
   6:        0x108b29670 - test1
   7:        0x108b295fd - main
./run.bash: line 8: 38948 Illegal instruction: 4  ./out

我擔心的不是那么簡單。 Rust任務不是普通線程,如pthreads或C中的其他線程。它們確實需要Rust運行時的一些支持,因此為了創建任務,您需要啟動運行時。 其中一種方法是從C程序調用Rust函數,然后調用另一個C函數:

#include <stdio.h>

extern int run(int argc, char** argv, void (*kont)(void));
extern void do_work();

void actual_main(void);

int main(int argc, char** argv) {
    return run(argc, argv, actual_main);
}

void actual_main(void) {
    printf("Hello from C program\n");
    do_work();
}

銹:

extern crate native;

#[no_mangle]
pub extern fn run(argc: int, argv: *const *const u8, kont: extern fn()) {
    native::start(argc, argv, proc() kont());
}

#[no_mangle]
pub extern fn do_work() {
    spawn(proc() {
        println!("Hello from task");
    });
}

編譯(在我的Linux機器上;如果你正在使用另一個操作系統,你可能需要調整它):

% rustc --crate-type staticlib --crate-name ex lib.rs
% gcc -c example.c
% gcc -L. -o example example.o -lex -lm -lpthread -lgcc_s -ldl

運行:

% ./example
Hello from C program
Hello from task

這確實需要您更改主要功能。 在任何情況下,從Rust(任務,Rust I / O,盒子等)訪問特定於運行時的函數的所有代碼都必須在調用堆棧中的“under” native::start()調用之下。 這是我所知道的最簡單的方法。 或者,如果這是可以接受的,你可以在Rust中編寫main()函數,因此你的可執行二進制文件將是rustc輸出,即使它的工作實際上會在C代碼中發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM