swift 无法直接访问 c 语言的Struct。只能通过指针的方式访问。
///////-----例子1开始-------////////
The c Lib API : mycapi.h
<code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",sans-serif; white-space: inherit;"><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">typedef</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">struct</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">{</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,145,175);">int</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> itype</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">;</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">double</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">*</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> dx</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">;</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">double</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">*</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> dy</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">;</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">}</span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjInfo</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">;</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">typedef</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjInfo</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">*</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjHandle</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">;</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjHandle</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjInit</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">const</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">char</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">*</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;">pFile</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">);</span></code>
add myapi.h as module
mySwiftcode :
normal; position: relative; overflow: auto; margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; font-size: 13px; width: auto; max-height: 600px; background-color: rgb(238,139);">import</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">Foundation</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0,139);">import</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> mycapiModule var h</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">:</span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjHandle</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">=</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjInit</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">(</span><span class="str" style="margin: 0px; padding: 0px; border: 0px; color: maroon;">"/home/a"</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> var o</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">:</span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; color: rgb(43,175);">MyObjInfo</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">=</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> h</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">.</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;">memory </span><span class="com" style="margin: 0px; padding: 0px; border: 0px; color: gray;">////to do somethings</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> </span><span class="com" style="margin: 0px; padding: 0px; border: 0px; color: gray;">//...</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> h</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">.</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;">destroy</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">()</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> h </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">=</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: black;"> nil print</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">(</span><span class="str" style="margin: 0px; padding: 0px; border: 0px; color: maroon;">"\(o.itype)"</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: black;">)</span></code>///////-----例子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))
Note that in this case thebuffer[10]
has been translated to Swift as a10-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)
ottom:1em; padding-top:0px; padding-bottom:0px; border:0px; font-size:15px; clear:both; color:rgb(34,the more complex is the struct,the more difficult is to use the default initializer.
2. Struct on the heap
This is similar to usingmalloc
andfree
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,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 转义方法
funcblankof<T>(type:T.Type) ->T{
letptr =UnsafeMutablePointer<T>.alloc(sizeof(T))
letval = ptr.memory
ptr.destroy()
returnval
}
varfs =blankof(C_Struct)
test(&fs))
在bridging-header中 需要定义 在Swift中使用的Struct 文件。
Bridging-Header.h
<code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas,sans-serif; white-space: inherit;">#include "user_input.h" </code>
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
normal; margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; font-size: 13px; overflow: auto; width: auto; max-height: 600px; background-color: rgb(238,sans-serif; white-space: inherit;">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)")</code>