Dav*_*han 13 c macos struct pointers swift
我知道这个答案,但这不是一回事 - 那就是传递一个用分配初始化的指针.
我正在与具有以下结构定义的C库连接:
typedef struct myStruct { unsigned char var [50]; } myStruct;
Run Code Online (Sandbox Code Playgroud)
有一个函数可以传递结构的地址 - 通常基于堆栈而不是堆,因此:
myStruct mine;
initMyStruct(&mine);
Run Code Online (Sandbox Code Playgroud)
这会初始化结构的内容 - 调用者不知道内存的内部格式,因此会混淆.
在Swift中,我正在创建一个类,它将封装结构和与其他C函数接口的接口.
class MyClass {
var mine : myStruct
init() {
initMyStruct(&mine)
// Error: Variable 'self.msg' passed by reference before being initialized
}
}
Run Code Online (Sandbox Code Playgroud)
我不能为我的生活弄清楚如何初始化结构,或者如果可以替代使用一个点.
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
Run Code Online (Sandbox Code Playgroud)
请注意,这是将已分配(基于堆栈)结构的地址传递给已导入的函数
CInt initMyStruct(str: CMutablePointer<myStruct>)
Run Code Online (Sandbox Code Playgroud)
它没有传递指向由有问题的C库分配的指针,这似乎是一个更常见的要求,并在其他地方得到解答.
Swift目前也不支持固定大小的数组.
我无法看到如何满足结构的初始化或使Swift认为它将通过调用完成.
任何帮助非常感谢!
Sul*_*han 11
首先,让我们定义用于测试的C代码:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在Swift中,我们有两个选择:
1.堆叠上的结构
var my_s: my_struct = ...
Run Code Online (Sandbox Code Playgroud)
但是,我们必须以某种方式初始化它.每个结构都有一个默认初始化程序
var my_s: my_struct = my_struct(buffer: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,buffer[10]
已将其转换为Swift作为a 10-tuple
.
现在我们可以致电:
my_struct_init(&my_s)
print("Buffer: \(my_s.buffer)") // Buffer: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Run Code Online (Sandbox Code Playgroud)
但是,结构越复杂,使用默认初始值设定项就越困难.
2.堆上的结构
这类似于在C中使用malloc
和free
:
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()
Run Code Online (Sandbox Code Playgroud)
结合两种方法
以下函数将初始化任何结构:
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)
Run Code Online (Sandbox Code Playgroud)
我不知道 initMyStruct 内部发生了什么...但假设它是一个函数,它将您想要复制到字段var 的字符串作为参数
我从未使用过 swift...但是在此代码中,您可以将结构体作为 C++ 类成员...
也许您可以使用仅封装该结构体的类?
#include <cstdio>
typedef struct myStruct { unsigned char var [50]; } myStruct;
void initMyStruct(myStruct *mine, char *ini)
{
int i = 0;
do
{
mine->var[i] = (unsigned char) ini[i];
} while(ini[i++]);
}
class MyClass
{
public:
myStruct st;
MyClass(char *parameter)
{
initMyStruct(&st, parameter);
}
};
int main()
{
MyClass c("Hakuna Matata!");
printf("%s\n", c.st.var);
}
Run Code Online (Sandbox Code Playgroud)
如果它使用一些 cstring 函数,可能会导致一些问题,因为指针是 unsigned char* 而不是 char*...
归档时间: |
|
查看次数: |
5854 次 |
最近记录: |