@@ -11,7 +11,7 @@ snappy includes a C interface (documented in
11
11
The following is a minimal example of calling a foreign function which will
12
12
compile if snappy is installed:
13
13
14
- ~~~~ no_run
14
+ ``` no_run
15
15
extern crate libc;
16
16
use libc::size_t;
17
17
@@ -24,7 +24,7 @@ fn main() {
24
24
let x = unsafe { snappy_max_compressed_length(100) };
25
25
println!("max compressed length of a 100 byte buffer: {}", x);
26
26
}
27
- ~~~~
27
+ ```
28
28
29
29
The ` extern ` block is a list of function signatures in a foreign library, in
30
30
this case with the platform's C ABI. The ` #[link(...)] ` attribute is used to
@@ -44,7 +44,7 @@ keeping the binding correct at runtime.
44
44
45
45
The ` extern ` block can be extended to cover the entire snappy API:
46
46
47
- ~~~~ no_run
47
+ ``` no_run
48
48
extern crate libc;
49
49
use libc::{c_int, size_t};
50
50
@@ -66,7 +66,7 @@ extern {
66
66
compressed_length: size_t) -> c_int;
67
67
}
68
68
# fn main() {}
69
- ~~~~
69
+ ```
70
70
71
71
# Creating a safe interface
72
72
@@ -79,7 +79,7 @@ vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous
79
79
length is number of elements currently contained, and the capacity is the total size in elements of
80
80
the allocated memory. The length is less than or equal to the capacity.
81
81
82
- ~~~~
82
+ ```
83
83
# extern crate libc;
84
84
# use libc::{c_int, size_t};
85
85
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@@ -89,7 +89,7 @@ pub fn validate_compressed_buffer(src: &[u8]) -> bool {
89
89
snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
90
90
}
91
91
}
92
- ~~~~
92
+ ```
93
93
94
94
The ` validate_compressed_buffer ` wrapper above makes use of an ` unsafe ` block, but it makes the
95
95
guarantee that calling it is safe for all inputs by leaving off ` unsafe ` from the function
@@ -103,7 +103,7 @@ required capacity to hold the compressed output. The vector can then be passed t
103
103
` snappy_compress ` function as an output parameter. An output parameter is also passed to retrieve
104
104
the true length after compression for setting the length.
105
105
106
- ~~~~
106
+ ```
107
107
# extern crate libc;
108
108
# use libc::{size_t, c_int};
109
109
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@@ -124,12 +124,12 @@ pub fn compress(src: &[u8]) -> Vec<u8> {
124
124
dst
125
125
}
126
126
}
127
- ~~~~
127
+ ```
128
128
129
129
Decompression is similar, because snappy stores the uncompressed size as part of the compression
130
130
format and ` snappy_uncompressed_length ` will retrieve the exact buffer size required.
131
131
132
- ~~~~
132
+ ```
133
133
# extern crate libc;
134
134
# use libc::{size_t, c_int};
135
135
# unsafe fn snappy_uncompress(compressed: *const u8,
@@ -159,7 +159,7 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> {
159
159
}
160
160
}
161
161
}
162
- ~~~~
162
+ ```
163
163
164
164
For reference, the examples used here are also available as an [ library on
165
165
GitHub] ( https://github.com/thestinger/rust-snappy ) .
@@ -208,7 +208,7 @@ A basic example is:
208
208
209
209
Rust code:
210
210
211
- ~~~~ no_run
211
+ ``` no_run
212
212
extern fn callback(a: i32) {
213
213
println!("I'm called from C with value {0}", a);
214
214
}
@@ -225,11 +225,11 @@ fn main() {
225
225
trigger_callback(); // Triggers the callback
226
226
}
227
227
}
228
- ~~~~
228
+ ```
229
229
230
230
C code:
231
231
232
- ~~~~ c
232
+ ``` c
233
233
typedef void (* rust_callback)(int32_t);
234
234
rust_callback cb;
235
235
@@ -241,7 +241,7 @@ int32_t register_callback(rust_callback callback) {
241
241
void trigger_callback() {
242
242
cb(7); // Will call callback(7) in Rust
243
243
}
244
- ~~~~
244
+ ```
245
245
246
246
In this example Rust's `main()` will call `trigger_callback()` in C,
247
247
which would, in turn, call back to `callback()` in Rust.
@@ -261,7 +261,7 @@ referenced Rust object.
261
261
262
262
Rust code:
263
263
264
- ~~~~ no_run
264
+ ``` no_run
265
265
#[repr(C)]
266
266
struct RustObject {
267
267
a: i32,
@@ -292,11 +292,11 @@ fn main() {
292
292
trigger_callback();
293
293
}
294
294
}
295
- ~~~~
295
+ ```
296
296
297
297
C code:
298
298
299
- ~~~~ c
299
+ ``` c
300
300
typedef void (* rust_callback)(void* , int32_t);
301
301
void* cb_target;
302
302
rust_callback cb;
@@ -310,7 +310,7 @@ int32_t register_callback(void* callback_target, rust_callback callback) {
310
310
void trigger_callback() {
311
311
cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust
312
312
}
313
- ~~~~
313
+ ```
314
314
315
315
## Asynchronous callbacks
316
316
@@ -389,13 +389,13 @@ the `link_args` attribute. This attribute is applied to `extern` blocks and
389
389
specifies raw flags which need to get passed to the linker when producing an
390
390
artifact. An example usage would be:
391
391
392
- ~~~ no_run
392
+ ``` no_run
393
393
#![feature(link_args)]
394
394
395
395
#[link_args = "-foo -bar -baz"]
396
396
extern {}
397
397
# fn main() {}
398
- ~~~
398
+ ```
399
399
400
400
Note that this feature is currently hidden behind the ` feature(link_args) ` gate
401
401
because this is not a sanctioned way of performing linking. Right now rustc
@@ -416,9 +416,9 @@ the compiler that the unsafety does not leak out of the block.
416
416
Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
417
417
this:
418
418
419
- ~~~~
419
+ ```
420
420
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
421
- ~~~~
421
+ ```
422
422
423
423
This function can only be called from an ` unsafe ` block or another ` unsafe ` function.
424
424
@@ -428,7 +428,7 @@ Foreign APIs often export a global variable which could do something like track
428
428
global state. In order to access these variables, you declare them in ` extern `
429
429
blocks with the ` static ` keyword:
430
430
431
- ~~~ no_run
431
+ ``` no_run
432
432
extern crate libc;
433
433
434
434
#[link(name = "readline")]
@@ -440,13 +440,13 @@ fn main() {
440
440
println!("You have readline version {} installed.",
441
441
rl_readline_version as int);
442
442
}
443
- ~~~
443
+ ```
444
444
445
445
Alternatively, you may need to alter global state provided by a foreign
446
446
interface. To do this, statics can be declared with ` mut ` so rust can mutate
447
447
them.
448
448
449
- ~~~ no_run
449
+ ``` no_run
450
450
extern crate libc;
451
451
452
452
use std::ffi::CString;
@@ -463,15 +463,15 @@ fn main() {
463
463
// get a line, process it
464
464
unsafe { rl_prompt = ptr::null(); }
465
465
}
466
- ~~~
466
+ ```
467
467
468
468
# Foreign calling conventions
469
469
470
470
Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
471
471
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
472
472
conventions. Rust provides a way to tell the compiler which convention to use:
473
473
474
- ~~~~
474
+ ```
475
475
extern crate libc;
476
476
477
477
#[cfg(all(target_os = "win32", target_arch = "x86"))]
@@ -481,7 +481,7 @@ extern "stdcall" {
481
481
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
482
482
}
483
483
# fn main() { }
484
- ~~~~
484
+ ```
485
485
486
486
This applies to the entire ` extern ` block. The list of supported ABI constraints
487
487
are:
@@ -541,3 +541,21 @@ with one of the non-nullable types, it is represented as a single pointer,
541
541
and the non-data variant is represented as the null pointer. So
542
542
` Option<extern "C" fn(c_int) -> c_int> ` is how one represents a nullable
543
543
function pointer using the C ABI.
544
+
545
+ # Calling Rust code from C
546
+
547
+ You may wish to compile Rust code in a way so that it can be called from C. This is
548
+ fairly easy, but requires a few things:
549
+
550
+ ```
551
+ #[no_mangle]
552
+ pub extern fn hello_rust() -> *const u8 {
553
+ "Hello, world!\0".as_ptr()
554
+ }
555
+ ```
556
+
557
+ The ` extern ` makes this function adhere to the C calling convention, as
558
+ discussed above in "[ Foreign Calling
559
+ Conventions] ( guide-ffi.html#foreign-calling-conventions ) ". The ` no_mangle `
560
+ attribute turns off Rust's name mangling, so that it is easier to link to.
561
+
0 commit comments