Access elements of a static fixed size array from a DLL in another DLL in Rust - dll

I'm compiling some information of an object into an .so, like:
#[no_mangle]
pub static a: [f32; 10] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
(simplified of course)
I need to have access to its values from another .so and thinking on simplifying the process, instead of creating a function that returns a Vec<f32> for example, I want to return a fixed size array since this will not change, like:
use libloading::{Library, Symbol};
...
unsafe {
let lib = Library::new("path/to/lib.so").unwrap();
let a: Symbol< * mut [f32; 10] > = lib.get(b"a\0").unwrap();
println!("{:?}", **a); // To check what is being retrieved
}
...
So far the output being printed is:
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Which is correct, but I cannot access it's elements, like:
let b = a[0];
When compiling:
error[E0608]: cannot index into a value of type `libloading::Symbol<'_, *mut [f32; 10]>`
How to have access to the values or even assign the whole array to a new one in the caller .so?

If you want to access the elements, you will have to dereference the Symbol and the mutable pointer first, like you already correctly did when printing the full array.
So if you want to access only the first element you will have to use (**a)[0] or (**a)[7] if you want to retrieve the eigth element.
Here is the full example based on the code in your question:
use libloading::{Library, Symbol};
fn main() {
unsafe {
let lib = Library::new("libarray_lib.dylib").unwrap();
let a: Symbol< * mut [f32; 10] > = lib.get(b"a\0").unwrap();
println!("{:?}", **a); // To check what is being retrieved
println!("{}", (**a)[0]); // Dereference a and access its first element
}
}

Related

Map boxed values to mutable dereferenced values in Rust

I have a iterator over a series of Boxed values. I would like to map this iterator to one over mutable references to the boxed values.
The following simplified example shows how this can be accomplished for immutable references. This example compiles fine.
let indices = [0usize, 1usize, 2usize];
let vec = vec![Box::new(1.0), Box::new(2.0), Box::new(3.0)];
let i = indices.iter().map(|index| vec[*index].deref()).map(|x| *x + 1.0);
However, for mutable references, like the example below, the compiler produces an error.
let indices = [0usize, 1usize, 2usize];
let mut vec = vec![Box::new(1.0), Box::new(2.0), Box::new(3.0)];
let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
The compiler error is the following:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src\port_graph/mod.rs:200:40
|
200 | let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime as defined on the body at 200:39...
--> src\port_graph/mod.rs:200:40
|
200 | let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
| ^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `vec`
--> src\port_graph/mod.rs:200:40
|
200 | let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
| ^^^
note: but, the lifetime must be valid for the scope of call-site for function at 200:39...
--> src\port_graph/mod.rs:200:40
|
200 | let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
| ^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that return value is valid for the call
--> src\port_graph/mod.rs:200:32
|
200 | let i = indices.iter().map(|index| vec[*index].deref_mut()).map(|x| *x = *x + 1.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How could this be fixed?
Edit: For a simple vector, one can simply do the following. However, the examples above are a simplicifation of a case where I want to iterate over a subset of nodes in a graph (petgraph crate), and I don't want to consume the graph itself.
let mut vec = vec![Box::new(1.0), Box::new(2.0), Box::new(3.0)];
let i = vec.iter_mut().map(|boxed| boxed.deref_mut()).map(|x| *x = *x + 1.0);
There is a tremendous difference between immutable and mutable references. The core principle of borrowing is:
Aliasing XOR Mutability
The Rust language guarantees that if you have a mutable reference, there is no other reference which aliases the same object.
In your case, instead of mapping again, let's collect... the addresses:
let c: Vec<_> = indices.iter().map(|index| vec[*index].deref())
.map(|x| x as *const _ as usize)
.collect();
println!("{:?}", c);
We get the list of addresses of elements in the vector.
The only reason those addresses differ is because the indices differ. If we are sneaky, and initialize indices to [0, 1, 2, 1], then we get aliasing.
If we can get aliasing based on a runtime property, then we should NOT also get mutability; and therefore the type system enforces this.
How is it enforced?
The vec is borrowed by the closure.
with deref, the closure borrows &Vec
with deref_mut, the closure borrows &mut Vec
You can witness the first one yourself:
let i = indices.iter().map(|index| vec[*index].deref())
.map(|x| x as *const _ as usize);
vec[0] = Box::new(3.0);
will fail with a note that the vector is already borrowed immutably by the closure.
The second one is a logical extension:
deref_mut takes a &mut self in argument,
which requires IndexMut which also takes a &mut self in argument,
therefore the closure requires mutable access to the vector.
So, each time you call the closure, it accesses a &mut Vec. Therefore, each time you call the closure NOTHING must alias this &mut Vec, and thus, no reference must leak outside the closure.
How is this achieved?
By tightening the lifetime of the reference that you get access to in the closure: each time you invoke the closure, you get a &'scope mut Vec reference where 'scope is the scope of the closure body and no more.
(This also relates to reborrowing and the fact that &mut T is not Copy: since you cannot be handed over a copy of the internally stored &mut T as it's not Copy, you are handed over a re-borrow &mut *vec which has a fresh lifetime).
What's the solution then?
Perform any and all computations directly in the closure where you have access to the Vec. In this closure, you have mutable access after all.
fn main() {
let indices = [0usize, 1usize, 2usize];
let mut vec = vec![Box::new(1.0), Box::new(2.0), Box::new(3.0)];
let c: Vec<_> =
indices.iter()
.map(|index| {
*vec[*index] = *vec[*index] + 1.0;
*vec[*index]
})
.collect();
println!("{:?}", c);
}
Correctly display [2, 3, 4].

Chaining iterators of different types

I get type errors when chaining different types of Iterator.
let s = Some(10);
let v = (1..5).chain(s.iter())
.collect::<Vec<_>>();
Output:
<anon>:23:20: 23:35 error: type mismatch resolving `<core::option::Iter<'_, _> as core::iter::IntoIterator>::Item == _`:
expected &-ptr,
found integral variable [E0271]
<anon>:23 let v = (1..5).chain(s.iter())
^~~~~~~~~~~~~~~
<anon>:23:20: 23:35 help: see the detailed explanation for E0271
<anon>:24:14: 24:33 error: no method named `collect` found for type `core::iter::Chain<core::ops::Range<_>, core::option::Iter<'_, _>>` in the current scope
<anon>:24 .collect::<Vec<_>>();
^~~~~~~~~~~~~~~~~~~
<anon>:24:14: 24:33 note: the method `collect` exists but the following trait bounds were not satisfied: `core::iter::Chain<core::ops::Range<_>, core::option::Iter<'_, _>> : core::iter::Iterator`
error: aborting due to 2 previous errors
But it works fine when zipping:
let s = Some(10);
let v = (1..5).zip(s.iter())
.collect::<Vec<_>>();
Output:
[(1, 10)]
Why is Rust able to infer the correct types for zip but not for chain and how can I fix it? n.b. I want to be able to do this for any iterator, so I don't want a solution that just works for Range and Option.
First, note that the iterators yield different types. I've added an explicit u8 to the numbers to make the types more obvious:
fn main() {
let s = Some(10u8);
let r = (1..5u8);
let () = s.iter().next(); // Option<&u8>
let () = r.next(); // Option<u8>
}
When you chain two iterators, both iterators must yield the same type. This makes sense as the iterator cannot "switch" what type it outputs when it gets to the end of one and begins on the second:
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
where U: IntoIterator<Item=Self::Item>
// ^~~~~~~~~~~~~~~ This means the types must match
So why does zip work? Because it doesn't have that restriction:
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
where U: IntoIterator
// ^~~~ Nothing here!
This is because zip returns a tuple with one value from each iterator; a new type, distinct from either source iterator's type. One iterator could be an integral type and the other could return your own custom type for all zip cares.
Why is Rust able to infer the correct types for zip but not for chain
There is no type inference happening here; that's a different thing. This is just plain-old type mismatching.
and how can I fix it?
In this case, your inner iterator yields a reference to an integer, a Clone-able type, so you can use cloned to make a new iterator that clones each value and then both iterators would have the same type:
fn main() {
let s = Some(10);
let v: Vec<_> = (1..5).chain(s.iter().cloned()).collect();
}
If you are done with the option, you can also use a consuming iterator with into_iter:
fn main() {
let s = Some(10);
let v: Vec<_> = (1..5).chain(s.into_iter()).collect();
}

How to convert Swift array into CFArray?

I'm trying to capture a window list in a Mac OS X app using Swift. The CGWindowListCreateImageFromArray function requires a CFArray. I've tried several things and this is the closest I've got. Or is there a better way to convert the array?
import Cocoa
// Example swift array of CGWindowID's
var windowIDs = [CGWindowID]();
windowIDs.append(1);
windowIDs.append(2);
// Convert to CFArray using CFArrayCreate
let allocator = kCFAllocatorDefault
let numValues = windowIDs.count as CFIndex
let callbacks: UnsafePointer<CFArrayCallBacks> = nil
var values: UnsafeMutablePointer<UnsafePointer<Void>> = nil
/* how do I convert windowIDs to UnsafeMutablePointer<UnsafePointer<Void>> for the values? */
let windowIDsCFArray = CFArrayCreate(allocator, values, numValues, callbacks);
let capture = CGWindowListCreateImageFromArray(CGRectInfinite, windowIDsCFArray, CGWindowImageOption(kCGWindowListOptionOnScreenOnly));
You can initialize your UnsafeMutablePointer with your array so long as you set your CGWindowIDs to CFTypeRef:
var windows: [CFTypeRef] = [1, 2]
var windowsPointer = UnsafeMutablePointer<UnsafePointer<Void>>(windows)
var cfArray = CFArrayCreate(nil, windowsPointer, windows.count, nil)
Converted Ian's answer to Swift 4:
let windows = [CGWindowID(17), CGWindowID(50), CGWindowID(59)]
let pointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: windows.count)
for (index, window) in windows.enumerated() {
pointer[index] = UnsafeRawPointer(bitPattern: UInt(window))
}
let array: CFArray = CFArrayCreate(kCFAllocatorDefault, pointer, windows.count, nil)
let capture = CGImage(windowListFromArrayScreenBounds: CGRect.infinite, windowArray: array, imageOption: [])!
let image: NSImage = NSImage(cgImage: capture, size: NSSize.zero)
Swift.print(image)
Arrays in Swift are bridged to NSArray, given they contain objects, e.g., conform to [AnyObject] type. Since CGWindowID is a UInt32, you need to convert it to NS family, array's map() method is an elegant approach.
var windows: [CGWindowID] = [CGWindowID(1), CGWindowID(2)]
var array: CFArray = windows.map({NSNumber(unsignedInt: $0)}) as CFArray
This, however, doesn't reflect on the actual CGWindowListCreateImageFromArray problem. Here's the working solution for that:
let windows: [CGWindowID] = [CGWindowID(17), CGWindowID(50), CGWindowID(59)]
let pointer: UnsafeMutablePointer<UnsafePointer<Void>> = UnsafeMutablePointer<UnsafePointer<Void>>.alloc(windows.count)
for var i: Int = 0, n = windows.count; i < n; i++ {
pointer[i] = UnsafePointer<Void>(bitPattern: UInt(windows[i]))
}
let array: CFArray = CFArrayCreate(kCFAllocatorDefault, pointer, windows.count, nil)
let capture: CGImage = CGWindowListCreateImageFromArray(CGRectInfinite, array, CGWindowImageOption.Default)!
let image: NSImage = NSImage(CGImage: capture, size: NSZeroSize)
Swift.print(image) // <NSImage 0x7f83a3d16920 Size={1440, 900} Reps=("<NSCGImageSnapshotRep:0x7f83a3d2dea0 cgImage=<CGImage 0x7f83a3d16840>>")>
I'm not great at ObjC, please correct if wrong, but from what I understand by playing with the SonOfGrab example and particular piece of code below is that the final pointer structure contains window ids (UInt32) not inside the memory cell (memory property of UnsafePointer instance), but inside memory address (hashValue property).
const void *windowIDs[2];
windowIDs[0] = 10;
windowIDs[1] = 20;
It's interesting, since values aren't stored in the memory, but inside the address descriptors, with oldest architectures being 32-bit UInt32 values fit perfectly into address pointers. Perhaps back in the days when the memory was a limiting factor this made a lot of sense and was a great approach. Discovering this all night in Swift in 2016 made me suicidal.
What's worse it fails in Xcode 7.2 playground with certain window ids, probably because of the way it handles memory, but works in the actual app.

Conflicting lifetime requirement for iterator returned from function

This may be a duplicate. I don't know. I couldn't understand the other answers well enough to know that. :)
Rust version: rustc 1.0.0-nightly (b47aebe3f 2015-02-26) (built 2015-02-27)
Basically, I'm passing a bool to this function that's supposed to build an iterator that filters one way for true and another way for false. Then it kind of craps itself because it doesn't know how to keep that boolean value handy, I guess. I don't know. There are actually multiple lifetime problems here, which is discouraging because this is a really common pattern for me, since I come from a .NET background.
fn main() {
for n in values(true) {
println!("{}", n);
}
}
fn values(even: bool) -> Box<Iterator<Item=usize>> {
Box::new([3usize, 4, 2, 1].iter()
.map(|n| n * 2)
.filter(|n| if even {
n % 2 == 0
} else {
true
}))
}
Is there a way to make this work?
You have two conflicting issues, so let break down a few representative pieces:
[3usize, 4, 2, 1].iter()
.map(|n| n * 2)
.filter(|n| n % 2 == 0))
Here, we create an array in the stack frame of the method, then get an iterator to it. Since we aren't allowed to consume the array, the iterator item is &usize. We then map from the &usize to a usize. Then we filter against a &usize - we aren't allowed to consume the filtered item, otherwise the iterator wouldn't have it to return!
The problem here is that we are ultimately rooted to the stack frame of the function. We can't return this iterator, because the array won't exist after the call returns!
To work around this for now, let's just make it static. Now we can focus on the issue with even.
filter takes a closure. Closures capture any variable used that isn't provided as an argument to the closure. By default, these variables are captured by reference. However, even is again a variable located on the stack frame. This time however, we can give it to the closure by using the move keyword. Here's everything put together:
fn main() {
for n in values(true) {
println!("{}", n);
}
}
static ITEMS: [usize; 4] = [3, 4, 2, 1];
fn values(even: bool) -> Box<Iterator<Item=usize>> {
Box::new(ITEMS.iter()
.map(|n| n * 2)
.filter(move |n| if even {
n % 2 == 0
} else {
true
}))
}

Inter-operability of Swift arrays with C?

How can one pass or copy the data in a C array, such as
float foo[1024];
, between C and Swift functions that use fixed size arrays, such as declared by
let foo = Float[](count: 1024, repeatedValue: 0.0)
?
I don't think this is easily possible. In the same way as you can't use C style arrays for parameters working with a NSArray.
All C arrays in Swift are represented by an UnsafePointer, e.g. UnsafePointer<Float>. Swift doesn't really know that the data are an array. If you want to convert them into a Swift array, you will have create a new object and copy the items there one by one.
let array: Array<Float> = [10.0, 50.0, 40.0]
// I am not sure if alloc(array.count) or alloc(array.count * sizeof(Float))
var cArray: UnsafePointer<Float> = UnsafePointer<Float>.alloc(array.count)
cArray.initializeFrom(array)
cArray.dealloc(array.count)
Edit
Just found a better solution, this could actually avoid copying.
let array: Array<Float> = [10.0, 50.0, 40.0]
// .withUnsafePointerToElements in Swift 2.x
array.withUnsafeBufferPointer() { (cArray: UnsafePointer<Float>) -> () in
// do something with the C array
}
As of Beta 5, one can just use pass &array
The following example passes 2 float arrays to a vDSP C function:
let logLen = 10
let len = Int(pow(2.0, Double(logLen)))
let setup : COpaquePointer = vDSP_create_fftsetup(vDSP_Length(logLen), FFTRadix(kFFTRadix2))
var myRealArray = [Float](count: len, repeatedValue: 0.0)
var myImagArray = [Float](count: len, repeatedValue: 0.0)
var cplxData = DSPSplitComplex(realp: &myRealArray, imagp: &myImagArray)
vDSP_fft_zip(setup, &cplxData, 1, vDSP_Length(logLen),FFTDirection(kFFTDirection_Forward))
The withUnsafePointerToElements() method was removed, now you can use the withUnsafeBufferPointer() instead, and use the baseAddress method in the block to achieve the point
let array: Array<Float> = [10.0, 50.0, 40.0]
array.withUnsafeBufferPointer { (cArray: UnsafePointer<Float>) -> () in
cArray.baseAddress
}
let's see what Apple do:
public struct float4 {
public var x: Float
public var y: Float
public var z: Float
public var w: Float
/// Initialize to the zero vector.
public init()
/// Initialize a vector with the specified elements.
public init(_ x: Float, _ y: Float, _ z: Float, _ w: Float)
/// Initialize a vector with the specified elements.
public init(x: Float, y: Float, z: Float, w: Float)
/// Initialize to a vector with all elements equal to `scalar`.
public init(_ scalar: Float)
/// Initialize to a vector with elements taken from `array`.
///
/// - Precondition: `array` must have exactly four elements.
public init(_ array: [Float])
/// Access individual elements of the vector via subscript.
public subscript(index: Int) -> Float
}