"cannot find function" 尝试遵循 FFI 示例时
"cannot find function" when trying to follow FFI example
我正在尝试开始使用 Rust FFI,所以我去了 the nomicon's documentation on FFI 并尝试复制 "Foreign calling conventions" 示例。
我编写了一些简单的代码,只是复制粘贴示例并尝试使用声明的函数:
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[=11=]", "NEW_ENV_VAR_VAL[=11=]");
println!("ret: {}", ret);
}
println!("Exit main");
}
这并没有真正做任何有用的事情,我只是想看看我是否可以 link 并调用一个函数而不会爆炸。
我从编译器中得到这个错误:
error[E0425]: cannot find function `SetEnvironmentVariableA` in this scope
--> src\main.rs:13:19
|
13 | let ret = SetEnvironmentVariableA("SOME_NEW_ENV_VAR[=12=]","NEW_ENV_VAR_VAL[=12=]");
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
示例是否过时?我错过了一些明显的东西吗?看来无论如何,我声明的 SetEnvironmentVariableA
应该在范围内。
我知道 winapi crate,但我正在尝试学习 Rust FFI;使用解决问题的现有板条箱将达不到目的。
Stargateur 的评论是正确的方向。删除以下行解决了问题:
#[cfg(all(target_os = "win32", target_arch = "x86"))]
本教程的 "Foreign calling conventions" 部分使用了 cfg
attribute,因此我认为让链接和调用约定起作用是某种神奇的一部分。 cfg
根本不是这样的。文档的 URL 单独解释了为什么我收到 "cannot find function" 错误:"conditional compilation".
我能够将示例扩展为一种你好世界:
#[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[=11=]".as_ptr(),"hellow world![=11=]".as_ptr());
println!("ret: {}", ret);
let mut dummy : u8 = 0;
let ret1 = GetEnvironmentVariableA("HELLO_WORLD_VAR[=11=]".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[=11=]".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");
}
我正在尝试开始使用 Rust FFI,所以我去了 the nomicon's documentation on FFI 并尝试复制 "Foreign calling conventions" 示例。
我编写了一些简单的代码,只是复制粘贴示例并尝试使用声明的函数:
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[=11=]", "NEW_ENV_VAR_VAL[=11=]");
println!("ret: {}", ret);
}
println!("Exit main");
}
这并没有真正做任何有用的事情,我只是想看看我是否可以 link 并调用一个函数而不会爆炸。
我从编译器中得到这个错误:
error[E0425]: cannot find function `SetEnvironmentVariableA` in this scope
--> src\main.rs:13:19
|
13 | let ret = SetEnvironmentVariableA("SOME_NEW_ENV_VAR[=12=]","NEW_ENV_VAR_VAL[=12=]");
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
示例是否过时?我错过了一些明显的东西吗?看来无论如何,我声明的 SetEnvironmentVariableA
应该在范围内。
我知道 winapi crate,但我正在尝试学习 Rust FFI;使用解决问题的现有板条箱将达不到目的。
Stargateur 的评论是正确的方向。删除以下行解决了问题:
#[cfg(all(target_os = "win32", target_arch = "x86"))]
本教程的 "Foreign calling conventions" 部分使用了 cfg
attribute,因此我认为让链接和调用约定起作用是某种神奇的一部分。 cfg
根本不是这样的。文档的 URL 单独解释了为什么我收到 "cannot find function" 错误:"conditional compilation".
我能够将示例扩展为一种你好世界:
#[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[=11=]".as_ptr(),"hellow world![=11=]".as_ptr());
println!("ret: {}", ret);
let mut dummy : u8 = 0;
let ret1 = GetEnvironmentVariableA("HELLO_WORLD_VAR[=11=]".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[=11=]".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");
}