Swift use c struct

后端 未结 3 968
孤城傲影
孤城傲影 2021-02-01 08:31

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. For example

In Bridging-Hea

相关标签:
3条回答
  • 2021-02-01 08:53

    After change my question, I got an answer.

    When the struct implements in hidden, this is called "opaque"

    so I can use COpaquePointer.

    var pointer: COpaquePointer = COpaquePointer.null()
    // some init code.
    init_pointer(pointer);
    
    0 讨论(0)
  • 2021-02-01 09:14

    Bridging-Header.h

    #include "user_input.h"
    

    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

    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)")
    
    0 讨论(0)
  • 2021-02-01 09:15

    You should be OK if you include the original header where Pointer is typedef-ed in ___Bridging-Header.h

    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

    Then your Swift code should be able to see the symbols declared in foo.h

    Update:

    What you need:

    1. Say "foo.h" is the header file where Pointer is typedef-ed. Also say that "foo.c" is the file where createPointer() is implemented.
    2. You'll need to create a Swift project in Xcode. Add "foo.h" and "foo.c" to the project.
    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).
    4. In "foo-Bridging-Header.h", you'll need to #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.

    For example, I have a Swift project. 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).

    Their contents are as follows:

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

    When run, this outputs:

    Hello, World!
    foo
    
    0 讨论(0)
提交回复
热议问题