简体   繁体   English

Swift使用c结构

[英]Swift use c struct

Sorry for the title, I can't find words to describe my question in few words. 对不起标题,我找不到用几句话来形容我的问题。

I already know that swift can use struct written in c. 我已经知道swift可以使用c编写的struct。 For example 例如

In Bridging-Header.h 在Bridging-Header.h中

typedef struct {
    int x;
    int y;
} Pointer;

then I can use Pointer directly. 然后我可以直接使用Pointer。

But in my case, I have a library written in C. There are many structs with hidden implement. 但就我而言,我有一个用C语言编写的库。有许多带有隐藏工具的结构。 For example: 例如:
In Briding-Header.h 在Briding-Header.h中

typedef struct Pointer Pointer;

I can't use Pointer any more, got unknown type. 我不能再使用Pointer了,得到了未知类型。 In my library Pointer is used as 在我的库中,Pointer用作

create_pointer(Pointer **pointer);

Any help is appreciated! 任何帮助表示赞赏!

PS I have no .h file which define struct Pointer. PS我没有定义struct Pointer的.h文件。 All details about Pointer is hide, access them by function, for example 关于Pointer的所有细节都是隐藏,例如,通过函数访问它们

int getx(Pointer *pointer);

Here is my full test code: 这是我的完整测试代码:
user_input.c user_input.c

#include <stdio.h>

#include "user_input.h"

struct Pointer {
    int x;
    int y;
};

void get_user_input(int *user_input) {
    scanf("%i", user_input);
}

void init_pointer(Pointer *point) {
    point->x = 20;
    point->y = 20;
}

user_input.h user_input.h

#ifndef __user_input_h__
#define __user_input_h__

typedef struct Pointer Pointer;

void init_pointer(Pointer *p);

#endif

Bridging-Header.h 转职Header.h

#include "user_input.h"

main.swift main.swift

import Foundation
var pointer:Pointer = Pointer(x:10, y:20)

Xcode give me this error: Pointer undefined Xcode给我这个错误:指针未定义

Bridging-Header.h 转职Header.h

#include "user_input.h"

user_input.c 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 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 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)")

You should be OK if you include the original header where Pointer is typedef-ed in ___Bridging-Header.h 如果在___ Bridging-Header.h中包含Pointer类型定义的原始标题,则应该没问题

So for example if you have foo.h where you declare your struct and your functions, then instead of doing any additional typdef calls in your bridging header just #import foo.h 因此,例如,如果你有foo.h,你声明你的结构和你的函数,那么不要在你的桥接头中进行任何额外的typdef调用#import foo.h

Then your Swift code should be able to see the symbols declared in foo.h 然后你的Swift代码应该能够看到foo.h中声明的符号

Update: 更新:

What you need: 你需要什么:

  1. Say "foo.h" is the header file where Pointer is typedef-ed. 假设“foo.h”是指针是类型定义的头文件。 Also say that "foo.c" is the file where createPointer() is implemented. 还要说“foo.c”是实现createPointer()的文件。
  2. You'll need to create a Swift project in Xcode. 您需要在Xcode中创建一个Swift项目。 Add "foo.h" and "foo.c" to the project. 将“foo.h”和“foo.c”添加到项目中。
  3. Add a header file to the project called "foo-Bridging-Header.h" (Sometimes Xcode asks if you want to create a Bridging Header when you add a .c or .m file to the project, but with the Developer Seed I haven't observed this to be consistent yet). 将一个头文件添加到名为“foo-Bridging-Header.h”的项目中(有时Xcode会询问您是否要在向项目添加.c或.m文件时创建桥接头,但是使用Developer Seed I避风港但是观察到它仍然是一致的。
  4. In "foo-Bridging-Header.h", you'll need to #include foo.h 在“foo-Bridging-Header.h”中,你需要#include foo.h
  5. Once you have done this, you should be able to call any of the symbols from "foo.h" from the "main.swift" file in your project. 完成此操作后,您应该可以从项目中的“main.swift”文件中调用“foo.h”中的任何符号。

For example, I have a Swift project. 例如,我有一个Swift项目。 In this project I have a Swift file (main.swift), a C header (test.h), a C source file (test.c), and a Bridging Header (test-Bridging-Header.h). 在这个项目中,我有一个Swift文件(main.swift),一个C头文件(test.h),一个C源文件(test.c)和一个Bridging Header(test-Bridging-Header.h)。

Their contents are as follows: 他们的内容如下:

  1. test.h: test.h:
 void printFoo(); 
  1. test.c: test.c的:
 #include <stdio.h> #include "test.h" void printFoo() { printf("foo\\n"); } 
  1. test-Bridging-Header.h: 测试桥接-Header.h:
 #import "test.h" 
  1. main.swift: main.swift:
 import Foundation println("Hello, World!") printFoo() 

When run, this outputs: 运行时,输出:

 Hello, World! foo 

After change my question, I got an answer. 在改变我的问题后,我得到了答案。

When the struct implements in hidden, this is called "opaque" 当struct在hidden中实现时,这被称为“不透明”

so I can use COpaquePointer. 所以我可以使用COpaquePointer。

var pointer: COpaquePointer = COpaquePointer.null()
// some init code.
init_pointer(pointer);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM