-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
FFI mechanism to declare a symbol for an array #54450
Comments
(As a side note, at a minimum Rust could at least check declared sizes of arrays against the size of the symbol they reference, at link time.) |
I think we probably can't derive the length at link time because we might be dynamically linked. Plus, the array type's size must be known to Rust before linking I think since you can implement for only some array lengths |
This might be possible as a user-defined macro along the lines of extern_symbol_ptr! {
pub static ptr symbol: *const c_char;
} expanding to something like pub static symbol: *const c_char = {
extern "C" {
#[link_name = "symbol"]
static inner: (); // or some more suitable dummy type
}
&inner as *const () as *const c_char
}; EDIT: It required a few changes to clear up warnings and the non- |
This declaration is a sugar for char symbol[11] = "…". Declaring So the most appropriate way to extern this definition in Rust would be extern "C" {
pub static symbol: [c_char; 11];
} Obviously, there are the cases where the length is unknown, in which case your best bet, I think, is extern "C" {
pub static symbol: c_char;
} and then taking the address of |
This is way out of rustc’s control and would require explicit support from the whole toolchain. I doubt anybody will be interested in spending the effort necessary to implement such a feature. |
On Sat, Sep 22, 2018 at 01:42:17AM -0700, Simonas Kazlauskas wrote:
> But if I have a C declaration
>
> ```
> char symbol[] = "hello world";
> ```
This declaration is a sugar for
> ```
> char symbol[11] = "…".
> ```
```
char symbol[12] = "hello world";
```
(since the string includes the `'\0'` at the end.)
Declaring such variable in C yields an incomplete type which you can only convert to to a pointer anyway. Ditto in C++.
I assume you mean declaring `extern char symbol[];` does this? (For the
original symbol, you can also, for instance, take the `sizeof` or
`typeof` it, as well as various other things, and get a usefully
different result than if you had a pointer.)
So the most appropriate way to extern this definition in Rust would be
```
extern "C" {
pub static symbol: [c_char; 11];
}
```
s/11/12/ again, but yes, true. Though it's unfortunate that this
requires specifying the length manually.
Obviously, there are the cases where the length is unknown, in which case your best bet, I think, is
```
extern "C" {
pub static symbol: c_char;
}
```
and then taking the address of `symbol` in the user code.
And then intentionally walking that pointer past the single character
declared? That seems rather unfortunate.
|
If I have a C declaration
I can declare that symbol in Rust as
But if I have a C declaration
I can't directly declare that in Rust in an immediately usable way. In this case,
symbol
refers directly to the array of characters; while in C it will "degrade" to a pointer if used in a context that expects a pointer, in Rust a declaration referring tosymbol
will refer to the characters directly. So, for instance, declaring it as a*c_char
will result in a pointer whose numeric value contains the firstsizeof::<*c_char>()
bytes of"hello world"
.Declaring
symbol
as a[c_char; 0]
and then obtaining and using its pointer seems wrong.I can think of a few useful ways to do this, one more straightforward than the other.
One would be to have a means of defining in an
extern "C"
block something that gets the value of the address of the symbol, just as if in C I'd writtenchar *symbol_ptr = symbol;
and then referenced that from Rust. That seems easy enough to do, modulo bikeshedding over the syntax to do so.Another would be to define
symbol
as a C array of unknown length. However, that seems unfortunate to deal with.The most ideal approach I can think of would be to define
symbol
as a[c_char; _]
(using the elided size syntax from rust-lang/rfcs#2545), and then infer the size from the symbol size:I don't know how feasible that would be, but it'd be incredibly convenient.
The text was updated successfully, but these errors were encountered: