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.
c
void func1(void)
{
return;
}
swift
func1()
C'est facile.
c
void func2(int a, int b)
{
return;
}
swift
func2(1,2)
C'est aussi facile, n'est-ce pas?
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?
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
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.
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
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
C'est tout pour le moment.
Recommended Posts