繁体   English   中英

如何验证`extern“C”`定义签名匹配实现

How to verify `extern "C"` definition signature matches implementation

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

给定以下文件:

main.rs

mod ffi;
mod impl_do_print;

fn main() {
    unsafe {
        ffi::do_print(42.0);
    }
}

ffi.rs

extern "C" {
    pub fn do_print(x: f32);
}

impl_do_print.rs

#[no_mangle]
pub extern "C" fn do_print(x: i32) {
    println!("{}", x);
}

显然,定义的f32和实现的i32不匹配。

当我执行此操作时,它会打印:

1047505936

我知道no_mangle被自动认为是unsafe ,但是有什么方法可以让编译器捕捉到不匹配的情况,或者我必须为此编写自己的 linter 吗?

用例:这个问题提出了生成的 FFI。 我能够以任何可能的方式修改实现,但我无法编辑 function 定义,因为它是通过bindgen生成的。

1 个回复

到目前为止,提出了两种可能可行的解决方案:

  • 使用ffi.rs方法自动生成一个实现,该方法只是将调用转发到我自己的实现。 这样,编译器将捕获不匹配的 arguments。
  • 使用ffi.rs为 function 生成type定义。 这样,您可以编写编译器检查来验证实现是否与定义匹配,如下所示: const _: fn_type = fn_impl

无论哪种方式,它似乎都需要 proc 宏或外部生成器。


经过更多的试验,我设法通过使用宏来实现编译时检查:

impl_do_print.rs

#[no_mangle]
pub extern "C" fn do_print(x: i32) {
    println!("{}", x);
}

macro_rules! check_implementation_type {
    ($t:ty, $name:ident) => {
        const _: $t = $name;
        const _: $t = crate::ffi::$name;
    };
}

check_implementation_type!(unsafe extern "C" fn(i32), do_print);

这仍然需要我为我实现的每个 function 编写一个check_implementation_type条目,但是如果ffi.rs或实现不匹配,它会给我一个可靠的编译时错误:

error[E0308]: mismatched types
  --> src/impl_do_print.rs:9:23
   |
9  |         const _: $t = crate::ffi::$name;
   |                       ^^^^^^^^^^^^^^^^^ expected `i32`, found `f32`
...
13 | check_implementation_type!(unsafe extern "C" fn(i32), do_print);
   | --------------------------------------------------------------- in this macro invocation
   |
   = note: expected fn pointer `unsafe extern "C" fn(i32)`
                 found fn item `unsafe extern "C" fn(f32) {ffi::do_print}`
   = note: this error originates in the macro `check_implementation_type` (in Nightly builds, run with -Z macro-backtrace for more info)
1 带有外部“C”的多重定义

有以下代码: 我无法弄清楚如何同时在头文件中进行声明和定义(不在 .H 中声明和在 .CPP 中定义),我尝试添加一个anonymous namespace ,也尝试添加static ,但没有运气 ...

2021-07-23 21:41:05 0 35   c++
2 C 中的外部声明和定义

据我所知,一个全局变量在 C 中可能有一到两个不同的存储类,并且声明可能用两个不同的关键字给出,相应地 静态变量只在声明模块内可见,不能导出。 在 extern 声明的情况下,变量位于所有链接模块的公共命名空间中,除非被静态变量遮蔽。 静态变量必须在它们的模块中定义,而外部变量可以在其他地方定 ...

3 如何验证gpg签名是否与公钥文件匹配?

我知道如何使用gpg验证这样: 但我真正想要做的是根据特定的公钥文件验证文件。 动机是从网站下载大文件并需要验证它们在使用之前没有被篡改的程序的一部分。 该网站将包含文件和签名。 该程序将附带GPG公钥。 当我将文件上传到网站时,我将使用相应的私钥对其进行签名(显然没有分发) ...

5 使用extern在C编程中进行声明和定义

在您看来,这似乎很简单,但是,这个问题在很多方面都困扰着我。 我的问题是关于c中变量的声明和定义。 互联网上实际上对此有很多解释,并且对此问题不仅有一种解决方案,因为在此问题上有很多观点。 我想知道这个问题的明确存在。 只是拿这个是一个声明还是定义?,当我使用prin ...

2015-06-22 10:47:48 2 110   c/ extern
6 C函数定义和外部关键字

我一直在尝试了解关于_sbrk函数遇到的链接错误,并偶然发现了库中的该函数定义。 现在,我知道extern对函数声明有什么作用,但是我不知道在函数定义中使用extern的含义... 有人知道这样使用extern有什么意思吗? 该文件位于Atmel软件框架(ASF)的asf/s ...

7 如何在C#中验证数字签名

我刚来这地方。 我正在学习 C# 中的数字签名。 生成证书后是本文档。 我阅读的其他文件: RSACng , X509Certificate2 。 我正在使用 Windows 10 Pro 1809、.Net Core 2.1、VSCode。 class Program { ...

8 如何在c#中验证openssl ecdsa签名?

我正在尝试在C#中验证使用openssl在C中完成的ECDSA签名。我被迫更改语言,因为签署文档的设备在linux上工作,检查签名的工作在.NET上工作。 据我所知,在C中实现算法的简单方法是使用命令行创建priv.pem,pub.pem和signature.bin文件。 我想念的是一种 ...

9 c#如何验证签名JWT?

我有一个令牌,一个包含公钥的文件,我想验证签名。 我试图基于此验证签名。 但是,decodedCrypto 和decodedSignature 不匹配。 这是我的代码: 我确定令牌的签名是有效的。 我尝试在https://jwt.io/上进行验证,结果显示签名已验证。 所以问题是编码、解码的 ...

10 如何验证 C# 中的 PayPal webhook 签名?

我有一个 C# 应用程序,它接收来自 PayPal 的 Webhook 通知,我想验证 Webhook 签名。 我已经找到了 2 个与同一问题相关的问题,但没有明确的工作解决方案 C# 中的 PayPal webhook 签名验证 如何验证 PayPal Webhook 签名? rsa.Veri ...

2021-04-12 10:13:12 0 43   c#/ paypal
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM