Appeler les fonctions du langage C depuis Swift

J'ai essayé d'appeler une fonction en langage C de Swift.

J'ai étudié comment passer des arguments lors de l'appel d'une fonction en langage C depuis Swift. Confirmé avec XCode 10.1.

Pour le moment, j'ai trouvé que dans Swift & n'est pas un opérateur d'adresse. Parfois, il est bon de deviner le type, mais dans le cas d'une structure auto-conçue, vous devez convertir le type correctement.

1 Aucun argument, aucune valeur de retour

c


void func1(void)
{
    return;
}

swift


func1()

C'est facile.

2 arguments int, pas de valeur de retour

c


void func2(int a, int b)
{
    return;
}

swift


func2(1,2)

C'est aussi facile, n'est-ce pas?

3 Argument int, valeur de retour int

c


int func3(int a, int b)
{
    return a+b;
}

swift


//Imprimer avec impression
print("func3()", func3(1,2))
//Attribuer à la variable
let c = func3(7,8)
print("func3()", c)

C'est aussi facile, n'est-ce pas?

4 Pointeur du tableau d'argument char

c


void func4(const char *in, char *out)
{
    unsigned long len = strlen(in) + 1;
    out[0] = 'A';
    memcpy(&out[1], in, len);
    return;
}

swift


var outstr : [CChar] = [0, 0, 0, 0, 0, 0]
func4("1234", &outstr)
print("func4()", outstr)
print("func4()", String(cString : outstr))

Si l'argument est const char * '', le passage d'un littéral String le convertira en chaîne de caractères C. Si l'argument est char * '', vous devez passer le pointeur de la variable.

Exemple d'exécution


func4() [65, 49, 50, 51, 52, 0]
func4() A1234

Structure à 5 arguments

c


struct location {
    int x;
    int y;
};

int func5(struct location loc);

c


int func5(struct location loc)
{
    loc.x += 1;
    loc.y += 1;
    return loc.x + loc.y;
}

swift


var l = location.init(x:1,y:2)
print("fnc5()", func5(l))

Vous pouvez utiliser init () pour initialiser la structure.

6 Pointeur de structure d'argument

h


struct location {
    int x;
    int y;
};

int func6(struct location *loc);

c


int func5(struct location loc)
{
    loc.x += 1;
    loc.y += 1;
    return loc.x + loc.y;
}

swift


var l = location.init(x:1,y:2)
withUnsafeMutablePointer(to: &l){
    let p = $0
    print("func6() before", p.pointee)
    func6(p)
    print("func6() after", p.pointee)
}

Utilisez withUnsafeMutablePointer () pour obtenir le pointeur de la structure. Le type de p est UnsafeMutablePointer . Utilisez p.pointee pour faire référence à un pointeur de structure. Les pointeurs de structure ne sont valides que dans le corps de withUnsafeMutablePointer ().

7 Passez le type de données comme pointeur et faites du pointeur de sortie un type de données.

Supposons que vous ayez une fonction d'encodeur écrite en C.

uint32_t hogeEnc(void *inp, void *outp);

Comme ça, une copie inutile s'est produite, mais cela a fonctionné.

    func encode(data:Data) -> Data {
        let input = UnsafeMutablePointer<UInt8>.allocate(capacity: 1920)
        let output = UnsafeMutablePointer<UInt8>.allocate(capacity: 1920)
        data.copyBytes(to: input, count: data.count)

        let enclen = hogeEnc(input, output)
        let encdata = Data(buffer: UnsafeMutableBufferPointer(start: output, count: Int(enclen)))
        
        input.deinitialize(count: 1920)
        output.deinitialize(count: 1920)

        return encdata
    }

Tout d'abord, générez des pointeurs d'entrée et de sortie pour sécuriser l'espace. Copie la chaîne d'octets de type de données de l'argument dans la zone pointée par le pointeur d'entrée. Appelez la fonction d'encodage C. Convertit le résultat encodé par la fonction d'encodage en type de données. À ce moment, le type UnsafeMutablePointer est converti en type UnsafeMutableBufferPointer. Relâchez enfin le pointeur. (Je ne sais pas si c'est nécessaire, mais juste au cas où.) Attention à ne pas accéder en dehors de la zone réservée en langage C.

C'est tout pour le moment.

Recommended Posts

Appeler les fonctions du langage C depuis Swift
Appeler un programme écrit en Swift depuis Processing (Java)
Faire un appel SOAP en C #
Appeler la bibliothèque Java à partir de C avec JNI
[Swift] Une note sur la fonction et la fermeture
Comment appeler le code Swift 5.3 depuis Objective-C
Conversion du pointeur de chaîne de langage C en type Swift String
[Swift 5.3] Apprendre d'un Swift Tour Swift [Xcode 12.1] <10/28 en construction>
ABC --013-A et B et C
Appeler Java depuis JRuby
ABC --036-A et B et C
ABC --010 --A & B & C
ABC --028 --A & B & C
ABC --015 --A & B & C
ABC --128 --A & B & C
ABC --012-A et B et C
ABC --018 --A & B & C
Appeler une méthode avec le bloc de rappel de Kotlin depuis Java
ABC --017 --A & B & C
ABC --029- A & B & C
ABC --022 --A & B & C
ABC --019 --A & B & C
ABC --030- A & B & C
ABC --127 --A & B & C
ABC --007 --A & B & C
Traitez les fonctions et fermetures Swift comme des pointeurs de fonction en langage C
ABC --132- A & B & C
ABC --026 --A & B & C
ABC --014- A & B & C
ABC --016 --A & B & C
ABC --031 --A & B & C
Générer des modèles de JSON à Swift, PHP, C #, JAVA
ABC --021 --A & B & C
ABC --025 --A & B & C
ABC --024 --A & B & C
ABC --027 --A & B & C
ABC --080- A & B & C
ABC --129- A & B & C & D
ABC --133- A & B & C & D
Utiliser le programme C de Ruby
ABC --122 --A & B & C & D
ABC --125- A & B & C & D
ABC --130- A & B & C & D
ABC --126 --A & B & C & D
À propos de l'ajout d'une fonction similaire
Passer le caractère de langage C * à Swift
J'ai essayé de générer une source de programme en langage C à partir de cURL
[Swift5] Comment communiquer de ViewController à Model et transmettre une valeur