Swift and C APIs (CoreVideo) - c

I'm trying to use CoreVideo with Swift but I'm getting this error:
let flags : CVOptionFlags = 0
CVPixelBufferLockBaseAddress(imageBuffer, flags)
^~~~~~~~~~~~~~~~~
Cannot convert the expression's type 'CVReturn' to type 'CVPixelBuffer!'
CVPixelBufferLockBaseAddress(imageBuffer, 0)
^~~~~~~~~~~~~~~~~
Cannot convert the expression's type 'CVReturn' to type 'CVOptionFlags'
Why does it matter that it can't convert the value if I'm not using it anyways? Should I be passing the 2nd argument differently?

I guess it will be working.
var tmp : COpaquePointer = CMSampleBufferGetImageBuffer(imageBuffer).toOpaque()
var pixelBuf : CVPixelBuffer = (Unmanaged<CVPixelBuffer>.fromOpaque(tmp)).takeUnretainedValue()
CVPixelBufferLockBaseAddress(pixelBuf, 0)

I'm not very familiar with CoreVideo, but I guess the problem is more with imageBuffer init, as your first implementation seems correct.
This code works, at least compiles:
var pixelBuffer : CVPixelBuffer?
let optionFlags : CVOptionFlags = 0
CVPixelBufferLockBaseAddress(pixelBuffer, optionFlags)

Related

OCaml type constructors in C = <unknown constructor>

I've written some OCaml bindings for some C code; they seem to work fine, except that, at the interpreter, the type constructor appears to be opaque to OCaml. So, for example:
# #load "foo.cma" ;;
# open Foo ;;
# let b = barbie "bar";;
val b : Foo.kung = <unknown constructor>
# let k = ken "kenny" ;;
val k : Foo.tza = <abstr>
I'm trying to get rid of the <unknown constructor> and replace it with a meaningful print.
The contents of foo.ml are:
type kung = Tsau of string [##boxed] ;;
type tza ;; (* Obviously, an abstract type *)
external barbie : string -> kung = "barbie_doll" ;;
external ken : string -> tza = "ken_doll" ;;
The C code is the minimal amount of code to get this to work:
CAMLprim value barbie(value vstr) { ... }
CAMLprim value ken(value vsttr) { ... }
The actual C code uses caml_alloc_custom() to hold stuff; and obviously has to return what caml_alloc_custom() alloced, so that it doesn't get lost. That's the core reason for using custom types: so I can return the custom malloc's.
Even though these types are abstract or opaque, I'd like to have the let expression print something meaningful. For example, perhaps this?
val b : Foo.kung = "Hi my name is bar"
val k : Foo.tza = "Yo duude it's kenny"
The second question would be: if it's possible to print something meaningful, what should it be? Obviously, the constructors were invoked with strings, so whatever is printed should include those string values...
The third question is: is it possible to specify types and type constructors in C? I suspect that the answer is "obviously no", because OCaml types are static, compile-time types, and are not dynamically constructable. But it never hurts to ask. I mean, the ocaml interpreter is able to deal with brand new type declarations just fine, so somehow, OCaml types aren't entirely static; there's some kind of 'dynamic' aspect to them. I've not found any documentation on this.
As suggested in a comment, the answer is to use #install_printer, which is briefly touched on in the toplevel documentation. This is but a hint: example code as follows (keeping with the earlier example).
In foostubs.ml:
(** Signature declarations for C functions *)
external kung_prt : kung -> string = "c_kung_str" ;;
(* Need to #install_printer kung_pretty ;;
* FYI, the OCaml documentation is confusing
* as to what a Format.formatter actually is:
* it is used like a C stream or outport. *)
let kung_pretty : Format.formatter -> kung -> unit =
function oport ->
fun x -> Format.fprintf oport "Hi %s" (kung_prt x) ;;
The printer in C would look like this:
CAMLprim value c_kung_str(value vkung)
{
CAMLparam1(vkung);
const char* name = String_val(vkung);
char buff[200];
strcpy(buff, "my name is ");
strncat(buff, name, 200);
CAMLreturn(caml_copy_string(buff));
}
Then, either you have to tell the user to #install_printer kung_pretty ;; or, better yet, provide the user with a setupfoo.ml that does this, and tell them to #use "setupfoo.ml".

Call C functions from Swift 4

I've generated C code from MATLAB by using the codegen tool. The function can be described as follows:
function [result] = calculate_data(my_matrix)
for idx = 1:length(my_matrix)
result = result + sum(my_matrix(idx,1:3));
end
end
When using the codegen tool, I explicitly stated that my_matrix is a type of double(:inf, 3). In other words, the number of rows is unbounded, but it will have 3 columns. When the code is generated, this is the function that is generated that I am to execute:
calculate_data(my_matrix : UnsafePointer<emxArray_real_T>!, result : UnsafeMutablePointer<emxArray_real_T>!)
emxArray_real_T is defined as follows in a different c file:
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
When I see my initialization options for the above class, this one in particular makes sense:
emxArray_real_T.init(data: UnsafeMutablePointer<Double>!, size: UnsafeMutablePointer<Int32>!, allocatedSize: Int32, numDimensions: Int32, canFreeData: boolean_T)
I've tried to follow this document as a means to wrap my head around how to call the generated C code, but I think I might be missing a basic step. Here is what I am doing:
// create an 2d array with some fake data
var mySampleData = [[Double]]();
for i in 0 ..< 3 {
mySampleData.append([1.1, 2.2, 3.3]);
}
// begin fulfilling requirements for emxArray_real_T
var data_pointer = UnsafeMutablePointer<Double>.allocate(capacity: 3);
data_pointer.initialize(from: mySampleData)
However, the above code throws an error stating that:
Generic parameter 'C' could not be inferred
I take it that I am then doing something completely wrong, and am probably on an incorrect path. There is a similar post that relates to my question, How to convert float[][] type array to "emxArray_real_T *x" , however the provided solution seems to be for C, as opposed to for Swift 4. How can I effectively call a C function using Swift 4, and meet the requirements of the emxArray_real_T.init method? Using fake data is ok to demonstrate the basic principle.
In a simple Xcode project with mocked C constructs for the struct emxArray_real_T and the function calculate_data I can run the following code successfully. To create an object of type emxArray_real_T I do
var data: [Double] = (0 ..< 12).map(Double.init)
var size: [Int32] = [4, 3]
var array = emxArray_real_T(
data: &data,
size: &size,
allocatedSize: 12,
numDimensions: 2,
canFreeData: false
)
This object can be passed to the function calculate_data like calculate_data(&array, nil). In a real application nil would be another array object. For the sake of simplicity it is just used as a placeholder here.
Your second issue can be solved by using the right types ([Double] instead of Double in line 6):
var mySampleData = [[Double]]();
for i in 0 ..< 3 {
mySampleData.append([i*1, i*2, i*3].map(Double.init));
}
let pointer = UnsafeMutablePointer<[Double]>.allocate(capacity: 3)
pointer.initialize(from: mySampleData, count: 3)
print((pointer + 0).pointee)
print((pointer + 1).pointee)
print((pointer + 2).pointee)
pointer.deallocate()
The output will be
[0.0, 0.0, 0.0]
[1.0, 2.0, 3.0]
[2.0, 4.0, 6.0]
as expected.
I have to admit that I used Swift 5.0.1. This should not make significant differences, though.

'withUnsafeBytes' is deprecated warning when passing void* argument to c function in swift 5

I have a library parsing FIT file in swift using an externally provided c library. The parsing function takes as argument a void * data.
To call the function, I was converting the data using data.withUnsafeBytes( { (ptr: UnsafePointer<UInt8>) in ...} to build the argument to the c function and it was working fine.
After the upgrade of Xcode to swift 5, I now get a deprecated warning
'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead
I couldn't work out how to fix the code to remove the deprecated warning. The code has been working fine and without warning in swift 4
I tried to change the argument in the closure to take UnsafeRawBufferPointer instead of the UnsafePointer but this resulted in an error in calling the function: Cannot convert 'UnsafeRawBufferPointer' to expected argument type 'UnsafeRawPointer?'
This is a small swift file to show the problem:
import Foundation
// Create sample data (Typically would be read from a file
let data = Data(repeating: 1, count: 10)
data.withUnsafeBytes( { (ptr : UnsafePointer<UInt8>) in
// call the c function with the void* argument
let value = readFITfile(ptr)
print( value )
})
And an example c function
unsigned readFITfile(const void * data){
//Silly example to show it works, just returning the value of pointer as int
//Typically would parse the data and return a structure
return (unsigned)data;
}
I saved a small repo with the above code here https://github.com/roznet/swift2c and the full scale project with the parsing of the file is here https://github.com/roznet/fit-sdk-swift
You have to change the closure argument to UnsafeRawBufferPointer and then take its baseAdress (which is a UnsafeRawPointer?, the Swift equivalent of void * in C):
data.withUnsafeBytes( { (ptr : UnsafeRawBufferPointer) in
let value = readFITfile(ptr.baseAddress)
// ...
})
The Swift compiler can also infer the closure argument type automatically:
data.withUnsafeBytes( { ptr in
let value = readFITfile(ptr.baseAddress)
// ...
})
For more information about this problem, see withUnsafeBytes Data API confusion in the Swift forum.
To get UnsafePointer now you should do something like that
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
if let ptrAddress = ptr.baseAddress, ptr.count > 0 {
let pointer = ptrAddress.assumingMemoryBound(to: UInt8.self) // here you got UnsafePointer<UInt8>
let value = readFITfile(ptr)
print( value )
} else {
// Here you should provide some error handling if you want ofc
}
}

How to call a C function from Swift whose name coincides with a structure?

In C, there are separate namespaces for functions and for structures. Module Darwin exports both struct flock and func flock. If I try to call the function, the compiler resolves the name to the structure initialiser:
let result: Int32 = Darwin.flock(fd, LOCK_EX)
^^^^^
Cannot invoke initializer
for type 'flock' with an argument list
of type '(Int32, Int32)'
If I try to resolve the name manually through a named import, I still get an error:
import func Darwin.flock
^^^^^^^^^^^^
Ambiguous name 'flock' in module 'Darwin'
Also no luck with a reference to a function:
let functionNotStruct: (Int32, Int32) -> Int32 = Darwin.flock
^^^^^^^^^^^^^^^^^^^^^^^
Cannot convert value of type 'flock.Type'
to specified type '(Int32, Int32) -> Int32'
Is there any way to tell the compiler I want the function and not the initialiser?
I cannot explain why it makes a difference, but omitting the module name makes it compile:
// Call `flock()`:
let result = flock(fd, LOCK_EX)
// Use `struct flock`:
var fl = flock()
fl.l_start = 0

Test type of value in Go

Im trying to validate a JSON object in Go. I'm trying to see if the 'tags' attribute is an array.( Later on I'll also want to know if another attribute is an object too).
I have reached to this. If I print reflect.TypeOf(gjson.Get(api_spec, "tags").Value() I get :
string // When the field is a string
[]interface {} // When the field is an array
map[string]interface {} // When the field is an object
But when trying to test this on the below code :
if ( gjson.Get(api_spec, "tags").Exists() ) {
if ( reflect.TypeOf(gjson.Get(api_spec, "tags").Value()) != "[]interface {}" ) {
// some code here ...
}
}
I get the below error code :
invalid operation: reflect.TypeOf(gjson.Get(api_spec, "tags").Value()) != "[]interface {}" (mismatched types reflect.Type and string)
Thanks in advance!
Use a type assertion to determine if a value is a []interface{}:
v := gjson.Get(api_spec, "tags").Value()
_, ok := v.([]interface{}) // ok is true if v is type []interface{}
Here's the code in the question modified to use a type assertion:
if gjson.Get(api_spec, "tags").Exists() {
if _, ok := gjson.Get(api_spec, "tags").Value().([]interface{}); !ok {
// some code here ...
}
}
There's no need to use reflection. If you do want to use reflection for some reason (and I don't see a reason in the question), then compare reflect.Type values:
// Get type using a dummy value. This can be done once by declaring
// the variable as a package-level variable.
var sliceOfInterface = reflect.TypeOf([]interface{}{})
ok = reflect.TypeOf(v) == sliceOfInterface // ok is true if v is type []interface{}
run the code on the playground
When you print a type to console, it's converted to a string; however, as you can see from the documentation for TypeOf, it does not return a string, it returns a reflect.Type. You can use Kind() to test programmatically what it is:
if reflect.TypeOf(gjson.Get(api_spec, "tags").Value()).Kind() != reflect.Slice {
Other Kinds you might be interested in are reflect.String and reflect.Map.
reflect.TypeOf returns a Type object. See docs at https://golang.org/pkg/reflect/#TypeOf
Your code should read:
if reflect.TypeOf(gjson.Get(api_spec, "tags").Value()).Name() != "[]interface {}" {
// some code here ...
}

Resources