未找到全局内存分配器,但需要一个;链接到 std 或将 `#[global_allocator]` 添加到实现 GlobalAlloc 特征的静态项

问题描述 投票:0回答:2

我目前正在使用 Rust 开发一个嵌入式开发项目。

但是,当我尝试在嵌入式端的应用程序中使用自己一直单独使用的库(并且作为标准库)时,出现了如标题所示的错误。

error: no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait

为了简洁和共享,我们将考虑如下可重现的文件夹结构。

- foo
   |__ app
   |    |__ src
   |    |    |__ main.rs
   |    |__ Cargo.toml
   |
   |__ some-crate 
        |__ src
             |__ lib.rs

main.rs 目前如下所示:

#![no_std]
#![no_main]
#![feature(default_alloc_error_handler)]
    
use sample_crate::add;
   
#[no_mangle]
extern "C" fn sample_main() {
    loop {
       add(2, 2);
    }
}

some-crate/lib.rs

#![cfg_attr(not(feature = "std"), no_std)]
#![warn(unused_extern_crates, dead_code)]

#[cfg(not(feature = "std"))]
#[allow(unused_imports)]
#[macro_use]
extern crate alloc;

pub fn add(left: usize, right: usize) -> usize {
    left + right
}

如果我不导入它可以编译

some-crate::add
。 我如何使用第三方板条箱进行编译?

rust embedded rust-no-std
2个回答
2
投票

如果您与

alloc
链接,您需要有一个全局分配器。这通常由
std
提供,但如果您省略
std
板条箱,那么您需要自己提供它,因为
no_std
环境不知道如何处理内存。

许多嵌入式系统都有良好的旧 C

malloc/free
函数的参考实现。如果您有这些或类似的内容,您可以绑定到这些 C 函数,然后在您的板条箱中的某个位置编写类似的内容:

use alloc::alloc::*;

/// The global allocator type.
#[derive(Default)]
pub struct Allocator;

unsafe impl GlobalAlloc for Allocator {
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
         malloc(layout.size() as u32) as *mut u8
     }
     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
         free(ptr as *mut c_void);
     }
}

/// If there is an out of memory error, just panic.
#[alloc_error_handler]
fn my_allocator_error(_layout: Layout) -> ! {
    panic!("out of memory");
}

/// The static global allocator.
#[global_allocator]
static GLOBAL_ALLOCATOR: Allocator = Allocator;


0
投票

您可能不需要分配器,只需定义它即可。这对我有用:

use alloc::{GlobalAlloc, Layout};

pub struct Allocator;

unsafe impl GlobalAlloc for Allocator {
    unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
        0 as *mut u8
    }
    unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
        unreachable!();     // since we never allocate
    }
}

#[global_allocator]
static GLOBAL_ALLOCATOR: Allocator = Allocator;
© www.soinside.com 2019 - 2024. All rights reserved.