【发布时间】:2019-12-05 19:56:42
【问题描述】:
我正在制作一个包含以下代码的 Rust 库:
pub mod my_module{
use std::os::raw::{c_int, c_double};
use std::collections::HashMap;
struct MyPrivateClass {
my_parameter:c_int
}
(...)
#[repr(C)]
pub struct MyPublicClass {
my_private_parameter:HashMap<String,MyPrivateClass>,
pub my_public_parameter:c_int,
pub my_other_public_parameter:c_double
}
(...)
}
我想使用 Objective-C 中的那个库。所以我使用 cbindgen 来生成一个 C 头文件。 在我的 Objective-C 项目中,我只需要访问 MyPublicClass 的公共字段。 但是生成的 C 标头包含我的公共结构的所有字段,包括私有字段。
这是生成的 C 标头的样子:
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct HashMap_String__MyPrivateClass HashMap_String__MyPrivateClass;
typedef struct {
HashMap_String__MyPrivateClass my_private_parameter;
int my_public_parameter;
double my_other_public_parameter;
} MyPublicClass;
在这种特殊情况下,HashMap 类型没有直接的 C 等效项,所以我不能使用这个 C 标头。
我只需要在我的 Rust 库中使用这个 HashMap。我不需要在 Objective-C 中使用它。
我怎样才能生成一个不暴露它而不破坏任何东西的 C 头文件?
【问题讨论】:
-
C 结构中不能有
HashMap。 C 不知道它的 ABI,C 也不知道它不能按位复制它。 C不知道它必须放弃它。我的猜测是,您实际上根本不希望 C 知道MyPublicClass,而只希望在 C 中指向它。在这种情况下,您只需声明typedef struct MyPublicClass MyPublicClass;。 -
C 和 C++ 不能忽略私有成员,因为它们需要知道类型的 大小。解决这个问题的唯一方法是使用指针成员,如前向声明的结构或 void*。
标签: c rust shared-libraries static-libraries c-header