Ich habe versucht, eine C-Sprachfunktion von Swift aus aufzurufen.
Ich habe untersucht, wie Argumente beim Aufrufen einer C-Sprachfunktion von Swift übergeben werden. Bestätigt mit XCode 10.1.
Vorerst habe ich festgestellt, dass in Swift & kein Adressoperator ist. Manchmal ist es gut, den Typ zu erraten, aber im Fall einer selbst erstellten Struktur müssen Sie den Typ richtig konvertieren.
c
void func1(void)
{
return;
}
swift
func1()
Es ist einfach.
c
void func2(int a, int b)
{
return;
}
swift
func2(1,2)
Das ist auch einfach, nicht wahr?
c
int func3(int a, int b)
{
return a+b;
}
swift
//Drucken mit Drucken
print("func3()", func3(1,2))
//Variable zuweisen
let c = func3(7,8)
print("func3()", c)
Das ist auch einfach, nicht wahr?
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))
Wenn das Argument `const char *`
lautet, wird es durch Übergeben eines String-Literal in eine C-Zeichenfolge konvertiert.
Wenn das Argument `char *`
ist, müssen Sie den Zeiger der Variablen übergeben.
Ausführungsbeispiel
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))
Sie können init () verwenden, um die Struktur zu initialisieren.
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)
}
Verwenden Sie withUnsafeMutablePointer (), um den Zeiger der Struktur abzurufen. Der Typ von p ist UnsafeMutablePointer
Angenommen, Sie haben eine in C geschriebene Encoderfunktion.
uint32_t hogeEnc(void *inp, void *outp);
Auf diese Weise ist eine nutzlose Kopie aufgetreten, die jedoch funktioniert hat.
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
}
Generieren Sie zunächst Zeiger für die Ein- und Ausgabe, um Speicherplatz zu sichern.
Kopiert die Datentyp-Byte-Zeichenfolge des Arguments in den Bereich, auf den der Eingabezeiger zeigt.
Rufen Sie die C-Codierungsfunktion auf.
Konvertiert das von der Codierungsfunktion codierte Ergebnis in den Datentyp. Zu diesem Zeitpunkt wird der Typ UnsafeMutablePointer
Das ist alles für jetzt.
Recommended Posts