Swift:将未初始化的 C 结构传递给导入的 C 函数 [英] Swift: Pass Uninitialized C Structure to Imported C function
问题描述
我知道这个答案,但是这不是一回事 - 那是传递一个指针以使用分配进行初始化.
I'm aware of this answer, but this is not the same thing - thats passing a pointer to be initialised with an allocation.
我正在与具有以下结构定义的 C 库交互:
I'm interfacing with a C library that has the following structure definition:
typedef struct myStruct { unsigned char var [50]; } myStruct;
有一个函数可以将结构的地址传递给它 - 通常基于堆栈而不是堆,因此:
There is a function to which you pass the address of the structure - normally stack based not heap, thus:
myStruct mine;
initMyStruct(&mine);
这会初始化结构体的内容 - 调用者不知道内存的内部格式,因此进行了混淆.
This initialises the content of the struct - the caller does not know the internal format of the memory, hence the obfuscation.
在 Swift 中,我正在创建一个类,该类将封装结构和接口,并与其他 C 函数对其进行操作.
In Swift, I'm creating a class which will encapsulate the structure and interface with other C functions which operates on it.
class MyClass {
var mine : myStruct
init() {
initMyStruct(&mine)
// Error: Variable 'self.msg' passed by reference before being initialized
}
}
我一生都无法弄清楚如何初始化结构,或者如果可以的话,也无法使用点代替.
I can't for the life of me work out how to initialise the structure, or use a point instead if that is an alternative.
mine = myStruct()
// Fails because you aren't providing the value of the member 'var'
mine = myStruct((CUnsignedChar(), CUnsignedChar(), /*... repeat to 50 */))
// Cannot find an overload for 'init' that accepts the arguments
请注意,这是将已分配的(基于堆栈的)结构的地址传递给已作为
Please note, this is passing the address of an already allocated (stack based) structure to a function that has been imported as
CInt initMyStruct(str: CMutablePointer<myStruct>)
它没有传递由相关 C 库分配的指针,这似乎是一个更常见的要求,并在其他地方得到了回答.
It is NOT passing a pointer to be allocated by the C library in question which seems to be a more common requirement and is answered elsewhere.
Swift 目前也不支持固定大小的数组.
Swift currently doesn't support fixed size arrays either.
我看不出如何满足结构的初始化或让 Swift 认为它会通过调用来完成.
I can't see how to satisfy the initialisation of the structure or make Swift think that it is going to be done so by the call.
非常感谢任何帮助!
推荐答案
首先,让我们定义用于测试的 C 代码:
First, let's define our C code for testing:
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;
}
}
在 Swift 中,我们有两个选择:
In Swift, we have two options:
1.堆栈结构
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))
请注意,在这种情况下,buffer[10]
已被转换为 Swift 作为 10-tuple
.
Note that in this case the buffer[10]
has been translated to Swift as a 10-tuple
.
现在我们可以调用:
my_struct_init(&my_s)
print("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.在堆上构造
这类似于在 C 中使用 malloc
和 free
:
This is similar to using malloc
and free
in C:
var my_s_pointer = UnsafeMutablePointer<my_struct>.allocate(capacity: 1)
print("Buffer: (my_s.buffer)") // Buffer: (some random values)
my_struct_init(my_s_pointer)
print("Buffer: (my_s_pointer.memory.buffer)") // Buffer: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
my_s_pointer.deallocate()
结合两种方法
以下函数将初始化任何结构:
The following function will initialize any struct:
func initStruct<S>() -> S {
let struct_pointer = UnsafeMutablePointer<S>.allocate(capacity: 1)
let struct_memory = struct_pointer.pointee
struct_pointer.dealloate()
return struct_memory
}
var my_s: my_struct = initStruct()
my_struct_init(&my_s)
这篇关于Swift:将未初始化的 C 结构传递给导入的 C 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!