Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow raw pointers in extern fn signature #164

Closed
dtolnay opened this issue Apr 28, 2020 · 6 comments · Fixed by #689
Closed

Allow raw pointers in extern fn signature #164

dtolnay opened this issue Apr 28, 2020 · 6 comments · Fixed by #689

Comments

@dtolnay
Copy link
Owner

dtolnay commented Apr 28, 2020

See #122 (comment) for the rationale.

mod ffi {
    extern "C" {
        type T;
        unsafe fn f(_: *mut T);
    }
    extern "Rust" {
        unsafe fn g(_: *mut T);
    }
}

The presence of *const or *mut in a function argument should enforce that the function is marked unsafe.

@dtolnay
Copy link
Owner Author

dtolnay commented Apr 28, 2020

Function pointers need to get the same check too. A function pointer type that has a raw pointer argument should be required to be specified as unsafe.

extern "Rust" {
    fn g(callback: unsafe fn(*mut T));
}

@dtolnay
Copy link
Owner Author

dtolnay commented Sep 5, 2020

In contrast to argument position, a pointer in return position should not enforce that the function is unsafe. #283

extern "C++" {
    type socc_examples_fixture;
    type SDIDevicePropInfoDataset;

    fn wait_for_IsEnable(
        self: &mut socc_examples_fixture,
        code: u16,
        expect: u16,
        retry_count: i32,
    ) -> *mut SDIDevicePropInfoDataset;
}

@felipesere
Copy link

I am trying to call the following function found in node.h from Node.js

// Set up per-process state needed to run Node.js. This will consume arguments
// from argv, fill exec_argv, and possibly add errors resulting from parsing
// the arguments to `errors`. The return value is a suggested exit code for the
// program; If it is 0, then initializing Node.js succeeded.
NODE_EXTERN int InitializeNodeWithArgs(std::vector<std::string>* argv,
                                       std::vector<std::string>* exec_argv,
                                       std::vector<std::string>* errors);

Given the std::vector<std::string>* ... arguments, I assume this falls into the problemspace for this issue?

Is there a workaround I could try?

My code currently looks like this:

#[cxx::bridge(namespace = "node")]
mod ffi {

    extern "C" {
        include!("node.h");

        fn InitializeNodeWithArgs(
            args: *const CxxVector<CxxString>,
            exec_args: *const CxxVector<CxxString>,
            errors: *const CxxVector<CxxString>,
        ) -> i32;
    }
}

This was referenced Nov 12, 2020
@adetaylor
Copy link
Collaborator

This is likely to be the next thing I look into adding. I haven't started yet. If anyone else thinks they'll do something in this area, please let me know so we can avoid duplication.

@adetaylor
Copy link
Collaborator

This proved easier than I thought - WIP linked just above.

I need to do some thinking about what happens if a raw pointer is included in some other type, e.g. a CxxVector: either adding some code in check.rs and in UI tests to ensure that's not possible, or make it possible - in which case the logic to check for the presence of unsafe will need to dig deeper in the type.

@Plecra
Copy link

Plecra commented Feb 2, 2021

Could the extern "Rust" functions be allowed without unsafe? I'd find the requirement confusing when it came up, since the Rust function would need to use unsafe internally to cause any soundness issue. (Of course, many functions would end up being unsafe by nature - I just worry that cxx enforcing it would make it less obvious that the author of the Rust function should document their requirements)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants