Swift:将未初始化的 C 结构传递给导入的 C 函数 [英] Swift: Pass Uninitialized C Structure to Imported C function

查看:10
本文介绍了Swift:将未初始化的 C 结构传递给导入的 C 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个答案,但是这不是一回事 - 那是传递一个指针以使用分配进行初始化.

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 中使用 mallocfree:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆