///-----例子1开始-------
The c Lib API : mycapi.h
typedef struct{
int itype;
double * dx;
double * dy;
}MyObjInfo;
typedef MyObjInfo * MyObjHandle;
MyObjHandle MyObjInit(const char *pFile);
add myapi.h as module
my swift code :
import Foundation
import mycapiModule
var h:MyObjHandle = MyObjInit("/home/a")
var o:MyObjInfo = h.memory
to do somethings
//...
h.destroy()
h = nil
print("\(o.itype)")
///-----例子1结束-------
在C函数定义的需要使用的Struct
typedef struct my_struct {
unsigned char buffer[10];
} my_struct;
void my_struct_init(my_struct *my_s) {
for (int i = 0; i < 10; i++) {
my_s->buffer[i] = (char) i;
}
}
In Swift, we have two options:
1. Struct on the stack
var my_s: my_struct = ...
However, we have to initialize it somehow. Every struct has a default initializer
var my_s: my_struct = my_struct(buffer: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
Note that in this case the buffer[10]
has been translated to Swift as a 10-tuple
.
Now we can call:
my_struct_init(&my_s)
println("Buffer: \(my_s.buffer)") // Buffer: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
However, the more complex is the struct, the more difficult is to use the default initializer.
2. Struct on the heap
This is similar to using malloc
and free
in C:
var my_s_pointer = UnsafeMutablePointer<my_struct>.alloc(1)
println("Buffer: \(my_s.buffer)") // Buffer: (some random values)
my_struct_init(my_s_pointer)
println("Buffer: \(my_s_pointer.memory.buffer)") // Buffer: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
my_s_pointer.destroy()
Combine both approaches
The following function will initialize any struct:
func initStruct<S>() -> S {
let struct_pointer = UnsafeMutablePointer<S>.alloc(1)
let struct_memory = struct_pointer.memory
struct_pointer.destroy()
return struct_memory
}
var my_s: my_struct = initStruct()
my_struct_init(&my_s)
C Struct 转义方法
func blankof<T>(type:T.Type) ->T {
let ptr =UnsafeMutablePointer<T>.alloc(sizeof(T))
let val = ptr.memory
ptr.destroy()
return val
}
var fs =blankof(C_Struct)
test(&fs))
在bridging-header中 需要定义 在Swift中使用的Struct 文件。
Bridging-Header.h
#include "user_input.h"
user_input.c
#include <stdlib.h>
struct Pointer {
int x;
int y;
};
Pointer *create_pointer() {
Pointer *p = malloc(sizeof(struct Pointer));
if (p) {
p->x = 20;
p->y = 20;
}
return p;
}
void delete_pointer(Pointer *p) {
free(p);
}
int pointer_x(Pointer *p) {
return p->x;
}
int pointer_y(Pointer *p) {
return p->y;
}
user_input.h
#ifndef __user_input_h__
#define __user_input_h__
typedef struct Pointer Pointer;
Pointer *create_pointer();
void delete_pointer(Pointer *p);
int pointer_x(Pointer *p);
int pointer_y(Pointer *p);
#endif
main.swift
import Foundation
var pointer: COpaquePointer = create_pointer()
println("\(pointer_x(pointer)), \(pointer_y(pointer))")
delete_pointer(pointer)
// Writing the wrapper class could be helpful.
class CPointer {
var _ptr: COpaquePointer
init() {
_ptr = create_pointer()
assert(_ptr, "Failed on create_pointer()")
}
deinit {
delete_pointer(_ptr)
}
var x: Int {
get { return Int(pointer_x(_ptr)) }
}
var y: Int {
get { return Int(pointer_y(_ptr)) }
}
}
var p = CPointer()
println("\(p.x), \(p.y)")