当前位置: 首页 > 知识库问答 >
问题:

尝试遵循FFI示例时“找不到函数”

禄俊逸
2023-03-14

我正试图开始使用Rust FFI,所以我去了FFI上的nomicon留档,尝试复制“外国呼叫约定”示例。

我编写了一段简单的代码,只需复制粘贴示例,并尝试使用声明的函数:

extern crate libc;

#[cfg(all(target_os = "win32", target_arch = "x86"))]
#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "stdcall" {
    fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
}

fn main() {
    println!("Enter main");
    unsafe {
        let ret = SetEnvironmentVariableA("SOME_NEW_ENV_VAR\0", "NEW_ENV_VAR_VAL\0");
        println!("ret: {}", ret);
    }
    println!("Exit main");
}

这真的没有什么用处,我只是想看看我是否可以链接并调用一个函数,而不会让一切都爆炸。

我从编译器中得到这个错误:

error[E0425]: cannot find function `SetEnvironmentVariableA` in this scope
  --> src\main.rs:13:19
   |
13 |         let ret = SetEnvironmentVariableA("SOME_NEW_ENV_VAR\0","NEW_ENV_VAR_VAL\0");
   |                   ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

这个例子过时了吗?我是不是漏掉了什么明显的东西?看起来不管怎样,我声明的SetEnvironmentVariableA应该在范围内。

我知道winapi板条箱,但我正在尝试学习Rust FFI;使用现有的板条箱来解决问题会破坏目的。

共有1个答案

祝允晨
2023-03-14

Stargateur的评论是正确的。删除以下行修复了该问题:

#[cfg(all(target_os = "win32", target_arch = "x86"))]

cfg属性用于本教程的“国外通话约定”部分,因此我认为,让链接和通话约定发挥作用是神奇的一部分。这根本不是cfg的工作方式。仅文档的URL就解释了为什么会出现“找不到函数”错误:“条件编译”。

我能够将这个例子扩展到一种hello world:

#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "stdcall" {
    fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> i32;
    fn GetEnvironmentVariableA(n: *const u8, v: *mut u8, s : u32) -> i32;
}

fn main() {
    println!("Enter main");
    unsafe {
        let ret = SetEnvironmentVariableA("HELLO_WORLD_VAR\0".as_ptr(),"hellow world!\0".as_ptr());
        println!("ret: {}", ret);
        let mut dummy : u8 = 0;
        let ret1 = GetEnvironmentVariableA("HELLO_WORLD_VAR\0".as_ptr(), &mut dummy, 0);
        println!("ret1: {}", ret1);
        if ret1 > 0 {
            let mut read = vec![0; ret1 as usize];
            let ret2 = GetEnvironmentVariableA("HELLO_WORLD_VAR\0".as_ptr(),read.as_mut_ptr(), ret1 as u32);
            let read_str = String::from_utf8(read).unwrap();
            println!("ret2: {}", ret2);
            println!("read_str: {}", read_str);
            println!("read_str.len(): {}", read_str.len());
        }
    }
    println!("Exit main");
}
 类似资料:
  • 链接到带有回调示例的外部c dll之后时出错。 我创建了Anneclib.dll并分散了它(和lib),甚至尝试了完整路径,但仍然得到相同的错误(但使用完整路径)。

  • 我尝试使用存储触发器测试gcloud函数。gcloud函数应该调用一个公共的gcloud服务,但需要身份验证。我可以在本地执行该函数而没有任何问题。但是在gcloud上,我可以在函数日志中找到一个NoClassDefFoundError。 无法执行函数。HelloGcs java。lang.NoClassDefFoundError:io/opencensus/trace/propagation/T

  • 问题内容: 更新: 建议删除行// =require_tree。已解决此问题。 我浪费了超过2天的时间来尝试遵循所有建议并解决我的问题。我正在尝试在Windows机器上关注http://ruby.railstutorial.org一书,但我一生无法克服以下令人讨厌的错误。 我尝试了所有建议,包括使用msi安装nodejs,使用execjs 1.3.0以及其他我什至不记得的东西。这是 gem文件 这

  • 更新:Colin关于删除行//=require_tree的建议。已经解决了这个问题。 我已经浪费了两天的时间,试图遵循每一个建议,并解决我的问题。我正在尝试在windows机器上学习http://ruby.railstutorial.org的书籍,但我一辈子都无法克服以下严重的错误。 我已经尝试了每一个建议,包括在msi中安装nodejs,使用ExecJS1.3.0和其他我已经记不清楚的东西。这是

  • 我已经成功地部署了这三个功能几个月了,现在它突然开始绊倒我。我已经有一段时间没有更改节点、npm或Firebase cli版本了。我升级了函数目录中的npm包,急于解决这个问题,但运气不好。为什么会发生这种情况?回购(悬浮滑板-v2分支):https://github.com/gdgfresno/valleydevfest2017/tree/hoverboard-v2/functions Ubun

  • 问题内容: 当我尝试使用Xcode 9.0 beta 5(9M202q)进行示例AVCAM swift时。我发现了错误。 对于架构x86_64的未定义的符号: “__T0So22AVCapturePhotoSettingsC12AVFoundation01_abC16SwiftNativeTypesACWP”,从引用:在CameraViewController.o __T05AVCam20Came