Macros 如何将C预处理器宏与Rust';什么是FFI?

Macros 如何将C预处理器宏与Rust';什么是FFI?,macros,c-preprocessor,ffi,rust,Macros,C Preprocessor,Ffi,Rust,我正在编写一些代码来连接用C编写的现有库。在我的Rust代码中,我希望能够使用CPP宏中的值。如果我有一个C include.h,它看起来像这样: #define INIT_FLAG 0x00000001 #[link(name="mylib")] extern { pub static init_flag: c_int = INIT_FLAG; } 我希望能够像这样在生锈的地方使用它: #define INIT_FLAG 0x00000001 #[link(name="mylib

我正在编写一些代码来连接用C编写的现有库。在我的Rust代码中,我希望能够使用CPP宏中的值。如果我有一个C include.h,它看起来像这样:

#define INIT_FLAG 0x00000001
#[link(name="mylib")]
extern {
    pub static init_flag: c_int = INIT_FLAG;
}
我希望能够像这样在生锈的地方使用它:

#define INIT_FLAG 0x00000001
#[link(name="mylib")]
extern {
    pub static init_flag: c_int = INIT_FLAG;
}
我看过其他的外国金融机构代码,我看到很多人 在Rust中复制这些值,而不是从FFI获取它们。 这似乎有点脆弱,我也希望能够处理 通过CPP宏定义的更复杂的事物。 只有在我确信自己的密码正确的情况下,才能在我的Rust文件上运行
cpp

CPP宏只用于简单的事情。

这是不可能的,我认为将来也不可能。C宏带来了太多的问题。如果要在锈迹源上运行
cpp
,可以手动执行

如果您不想这样做,并且如果有很多常量,您也不想将它们的值从C代码复制到Rust,那么您可以制作一个C包装器,它将为全局变量提供这些值:

#定义初始标志0x00000001
...
const int init_flag=init_flag;
编译此文件,从中创建静态库,并像往常一样链接到它:

$gcc-c init_flag.c
$ar r libinitflag.a init_flag.o
锈源:

使用std::libc;
#[链接(name=“initflag”,kind=“static”)]
外行{
pub static init_标志:libc::c_int;
}

锈源几乎与您试图实现的目标相同。但是,您需要C glue对象文件。

这仅仅是不可能的,因为C宏常量在运行时并不表示任何对象或实体。这是因为
cpp
预处理器甚至在编译之前就执行宏扩展(并处理rest指令)。考虑下面的片段:

#define INIT_FLAG 0x00000001

/* some code */

unsigned dummy() { return INIT_FLAG; }

/* some other code */
在代码段上运行
cpp
会产生预处理的代码(所谓的编译单元或翻译单元),其中所有出现的
INIT_标志
都被字面
0x00000001
替换:

unsigned dummy() { return 0x00000001; }

然后编译单元被编译,生成目标文件,但现在没有
INIT_FLAG
的痕迹。因此,在针对对象文件进行链接时,您不能引用
INIT_FLAG
:它根本不包含这样的符号。

我使用build.rs和cc::build::new()尝试过这样做,但它似乎不喜欢链接器的工作方式。所有-L和-L标志看起来都正常,但它在链接时对静态变量有未定义的引用。您可能需要将代码更改为
extern const int
,因为
const int
s是private@xcvr不知道你是什么意思。在C语言中,所有项目都显示在对象文件中,除非它们被标记为
static
<代码>外部只需要引用C代码中的其他项目,不需要“导出”任何东西,因为没有
静态
所有项目都是“导出”的。我的错误。这是C++与C语言不同的地方之一。