In Rust, extern C functions can be declared in the outer scope:
#[link(name = "some_lib")]
extern "C" {
pub fn foo(path: *const c_char);
pub fn bar(path: *const c_char);
pub fn baz(path: *const c_char);
pub fn fez(path: *const c_char);
}
While acceptable, each function needs to be accessed directly foo() bar()... etc.
Is it possible to declare these in a way they can be accessed using a common prefix?
Example of how encapsulation could work:
namespace some_lib {
#[link(name = "some_lib")]
extern "C" {
pub fn foo(path: *const c_char);
// ... etc ...
}
}
fn some_rust_function() {
unsafe {
some_lib::foo(); // <-- example usage
}
}
Is something like this possible?
Just use a module.
mod ffi {
extern "C" {
pub fn exit(_: i32) -> !;
}
}
fn main() {
unsafe { ffi::exit(1); }
}
Related
What I want to make is a function, that returns itself, so I can call it like this:
foo()()...()
In C# it would be done via delegates:
delegate SelfFunc SelfFunc();
static void Main() {
SelfFunc foo = null;
foo = () => {
return foo;
};
foo()()...();
}
Anticipating questions like "why implement such silly behavior?": I want to sum numbers in a very strange way using single function continues calls: foo(1)(2)(3)() = 6, but in this question I just want to know how to return function itself. Example realization of this method that I made in C#. This is all just for fun and to learn Rust:
static int sum = 0;
delegate dynamic InfFunc(int i = int.MaxValue);
static void InfFuncTest() {
InfFunc f = null;
f = (int i) => {
if(i == int.MaxValue) {
return sum;
}
sum += i;
return f;
};
var g = f;
var value = g(1)(2)(3)();
Console.WriteLine(value);
}
A function that returns itself is possible on nightly.
First you need to enable the features unboxed_closures and fn_traits.
Then you can define a struct which, when called, returns self. The full code looks something like this:
#![feature(unboxed_closures, fn_traits)]
struct SelfFunc;
impl FnOnce<()> for SelfFunc {
type Output = SelfFunc;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self
}
}
Then you can call the function as many times as you want:
fn main() {
let f = SelfFunc;
f()()()()()();
}
Based on #cameron1024's answer, you can "overload" using traits, but you will need 2 structs to handle the empty case properly of foo() (here called Add) without any arguments returning 0.
#![feature(unboxed_closures, fn_traits)]
struct Add;
impl FnOnce<(u32,)> for Add {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
AddImpl(args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
0
}
}
struct AddImpl(u32);
impl FnOnce<()> for AddImpl {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
impl FnOnce<(u32,)> for AddImpl {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Self(self.0 + args.0)
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
dbg!( Add() );
}
Playground
If you do not care about the no-args foo() requirement, you can make Add a tuple struct instead and remove AddImpl:
#![feature(unboxed_closures, fn_traits)]
struct Add(u32);
impl FnOnce<(u32,)> for Add {
type Output = Add;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Add(self.0 + args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
//dbg!( Add() ); // doesn't compile
}
Playground
Although I should note that this likely isn't such a great idea, using an slice/iterator would likely result in cleaner code:
fn main() {
dbg!([1, 2, 3].iter().copied().sum::<u32>());
}
Playground
this example grabbed from geeksforgeeks.
// C++ program to demonstrate function
// declaration outside class
#include <bits/stdc++.h>
using namespace std;
class Geeks
{
public:
string geekname;
int id;
// printname is not defined inside class definition
void printname();
// printid is defined inside class definition
void printid()
{
cout << "Geek id is: " << id;
}
};
// Definition of printname using scope resolution operator ::
void Geeks::printname()
{
cout << "Geekname is: " << geekname;
}
int main() {
Geeks obj1;
obj1.geekname = "xyz";
obj1.id=15;
// call printname()
obj1.printname();
cout << endl;
// call printid()
obj1.printid();
return 0;
}
I mean, function like printname in this example.
And in rust..., this example grabbed from exercism and I modified little bit.
// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]
pub struct User {
name: String,
age: u32,
weight: f32,
}
impl User {
pub fn new(name: String, age: u32, weight: f32) -> Self;
pub fn name(&self) -> &str;
...
...
}
pub fn User::name(&self) -> &str {
unimplemented!()
}
...
...
like this or somewhat difference, but declare first definition later.
Sorry for my bad english, and therefore I included many lines of code and I needed to add some more detail because SO wants that.
There's no way to do this in Rust?
You can do the same thing in Rust. You can implement particular struct methods, from anywhere inside the crate.
This is mostly pointless in Rust, but I'm going to provide an example where this might prove useful.
Soundness concerns leak to the surrounding module, and thus you can reduce the scope of this issue by doing this:
mod a {
pub struct A;
impl A {
pub fn a(&self) {
// here we can't access any unsafe functions specific to A
// unsafe { some_unsafe_helper() }; // compiler error
println!("Called ::crate::a::A::a implemented in ::crate::a");
}
}
mod less_safe {
unsafe fn some_unsafe_helper() {}
impl super::A {
pub fn b(&self) {
// here we have to uphold invariants, in this case, by doing nothing
unsafe { some_unsafe_helper() };
println!("Called ::crate::a::A::b implemented in ::crate::a::less_safe");
}
}
}
}
fn main() {
let example = a::A;
example.a();
example.b();
}
This prints:
Called ::crate::a::A::a implemented in ::crate::a
Called ::crate::a::A::b implemented in ::crate::a::less_safe
Playground
Is there a way to declare a generic trait that takes a function as the generic argument and uses it?
To clarify (Non-functioning code):
pub trait Test<F, T> where F: Fn(i32) -> T {
fn test(arg: i32) -> T {
let func: F;
func(arg)
}
}
You can associate specific functions when implementing a trait (didn't knew about this until now):
fn func() -> String {
String::from("hello")
}
trait MyTrait {
const FUNC: fn() -> String;
}
struct MyType;
impl MyTrait for MyType {
const FUNC: fn() -> String = func;
}
fn main() {
println!("{}", (MyType::FUNC)()); // prints hello
}
Playground
You can implement it somehow like this:
trait MyTrait<V: Sized + Fn() -> &'static str>: Sized {
fn construct(fun: V) -> Self;
fn get_fn(&self) -> &V;
fn call_inner(&self) {
println!("{}", (self.get_fn())());
}
}
struct FuncitonContainer<V>
where
V: Sized + Fn() -> &'static str,
{
f: V,
}
impl<V> MyTrait<V> for FuncitonContainer<V>
where
V: Sized + Fn() -> &'static str,
{
fn construct(fun: V) -> Self {
Self { f: fun }
}
fn get_fn(&self) -> &V {
&self.f
}
}
fn main() {
fn get_hello() -> &'static str {
"Hello"
}
FuncitonContainer::construct(get_hello).call_inner();
FuncitonContainer::construct(|| "World").call_inner();
}
It preserves function info and allows to use closures too. However, using it can be little more complex than Mihir's answer.
You can also look how Rust iterators are implemented: Rust iterators implementation
When storing raw pointers to functions in structs in Rust, the behaviour of the program can change in unexpected ways depending on the mutability of the raw pointer.
Using const pointers gives the expected result.
The following code can also be viewed on the playground:
type ExternFn = unsafe extern "C" fn() -> ();
unsafe extern "C" fn test_fn() {
println!("Hello!");
}
mod mut_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *mut ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&mut (test_fn as ExternFn) as *mut _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
mod const_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *const ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&(test_fn as ExternFn) as *const _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
// use const_ptr::FunctionHolder;
use mut_ptr::FunctionHolder;
fn check_holder(holder: &FunctionHolder) -> bool {
let good = FunctionHolder::new();
println!("parameter = {:#?}", holder);
println!("expected = {:#?}", good);
holder == &good
}
fn main() {
let f0 = FunctionHolder::new();
println!("{:?}", f0);
let f1 = FunctionHolder::new();
println!("{:?}", f1);
// uncomment this line to cause a segfault if using the
// mut_ptr version :-(
// f1.call();
assert!(check_holder(&f1));
}
In the const_ptr module, the code behaves as expected: The pointer value stored in the FunctionHolder struct is the same regardless of where the function is called, and using the FunctionHolder::call method calls the function as required.
In the mut_ptr module, there are some unexpected differences:
The FunctionHolder::new method returns a struct holding a different value depending on the function in which it is called,
The FunctionHolder::call method causes a segfault.
fn() -> () is a function pointer. *const fn() -> () and *mut fn() -> () are function pointer pointers.
You want to use much simpler code, which also means there's no difference between the two implementations:
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: Option<ExternFn>,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: Some(test_fn as ExternFn),
}
}
pub fn call(&self) {
if let Some(f) = self.function {
unsafe { f(); }
}
}
}
As mentioned in the comments, taking a mutable reference to a literal value constructs a new value each time:
fn main() {
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
}
0x55a551c03a34
0x55a551c03a34
0x55a551c03a34
0x7ffd40dbb95c
0x7ffd40dbb9bc
0x7ffd40dbba1c
Immutable references to literals have implicit static promotion:
let a = &42;
// More-or-less
static HIDDEN: i32 = 42;
let a = &HIDDEN;
Mutable references to literals desugar to effectively:
let mut hidden: i32 = 42;
let a = &mut hidden;
By using raw pointers, you lose the support of the borrow checker to point out that your references don't live long enough for the mutable case.
See also:
Why is it legal to borrow a temporary?
Why can I return a reference to a local literal but not a variable?
What are the semantics of mutably borrowing a literal in Rust?
How can I get the caller type in my function?
struct A;
struct B;
impl A {
fn new() -> Self {
A
}
fn call_function(&self) {
B::my_function();
}
}
impl B {
pub fn my_function() {
println!("Hello");
// println!("{}" type_of_the_caller) // I want to get type A here
// Is it possible to get the caller type which is A in this case?
}
}
fn main() {
let a = A::new();
a.call_function();
}
Here is the working code in playground. This is simplified code for an example.
Rust doesn't have any machinery like this built-in. If you want to know some context inside a function then you'll need to pass it in as an argument.
Also, Rust doesn't have a way to get the name of a type, so you'd have to provide that too. For example, with a trait:
trait Named {
fn name() -> &'static str;
}
impl Named for A {
fn name() -> &'static str {
"A"
}
}
Which you might use like this:
impl B {
pub fn my_function<T: Named>(_: &T) {
println!("Hello");
println!("{}", T::name());
}
}
You just have to pass in the caller when you call it:
impl A {
fn call_function(&self) {
B::my_function(self);
}
}
Outputs:
Hello
A
You can have the compiler write the boilerplate by creating a macro and making use of the stringify! macro.
struct A;
struct B;
struct C;
trait Named {
fn name() -> &'static str;
}
macro_rules! make_named {
( $($x:ty),* ) => {
$(
impl Named for $x {
fn name() -> &'static str {
stringify!($x)
}
}
)*
};
}
make_named!(A, B);
make_named!(C);
fn main() {
println!("{:#?}", A::name());
println!("{:#?}", B::name());
println!("{:#?}", C::name());
}
playground