So rufen Sie Rust aus anderen Sprachen auf

8

Zuvor, als die Codebasis in C ++ war, hatte ich C ++ - Wrapper-Dateien, die mit der Codebasis verlinkten, und ich würde swig (Version 3 für C ++ 11-Unterstützung) ausführen, um die Schnittstellendateien für das Ziel zu generieren Sprache (Python, JavaScript, C # usw.). Dann werden natürlich alle diese Dateien und Bibliotheken in ein gemeinsames Objekt kompiliert und aus den benötigten Sprachen aufgerufen. Jetzt wird die Codebasis in Rost geändert. Also zum Schlucken zur Arbeit habe ich folgendes:

  1. Hauptrostcode-Datei, die in eine rlib kompiliert wird.
  2. Rust-Wrapper-Datei, die in die Hauptcode-Basis aufruft, aber die no_mangle - und extern -Syntax für FFI verwendet und in eine staticlib kompiliert.
  3. Eine C-Datei, die den Rost-Wrapper aufruft und eine Kopie davon ist.

Jetzt benutze ich swig für die C-Datei, erhalte die Schnittstellendatei für die Zielsprache, kombiniere alle Dateien (Schritte zwei und drei) und die SWIG-Schnittstellendatei) in ein gemeinsames Objekt und rufe aus der Zielsprache an.

Also:

  1. Ist der Ansatz in Ordnung?

  2. Ich kann freie Funktionen zum Arbeiten bekommen. Ich bin jedoch verwirrt darüber, wie man Mitgliedsfunktionen (Methoden) zum Laufen bringt. In C ++ ist der erste Parameter der Member-Funktionen der implizite this -Zeiger. Also könnte ich ein void* handle an die Klasse oder struct an die C-Schnittstelle zurückgeben, das es an andere weitergeben würde, die es speichern wollten (zB jsctypes für Firefox) und dann wieder reinterpret_cast it an das konkrete / tatsächliche erhalten Geben Sie die Elementfunktion ein und rufen Sie sie auf. Wie mache ich das mit Rust?

z.B. für

%Vor%

Wie greife ich dann auf diese Memberfunktionen auf ein Objekt von A (sollte nicht verwaltet werden und auf dem Heap, denke ich?) von Zielsprachen (Python, C, etc.) oder einfach nur von einer C-Schnittstelle?

    
ustulation 07.05.2015, 06:46
quelle

2 Antworten

3

Nun, Methoden sind nur normale Funktionen, und wie Chris sagte, self Argument hat eine implizite Verbindung mit Self type. Mit Ihrem Beispiel (leicht modifiziert) mit Funktionen aus C-Code sollte einfach sein:

%Vor%

Beachten Sie, dass ich extern hinzugefügt habe, um die Aufrufkonvention zu ändern, und #[no_mangle] , um Namensfehlern und #[repr(C)] in der Struktur zu vermeiden. Letzteres ist nicht notwendig, wenn Ihr Code Box es der Struktur erzeugt und diese als rohe Zeiger an C übergeben. Ich bin mir jedoch nicht sicher, wie #[no_mangle] die Trait-Methoden beeinflussen könnte, wenn es mehr als einen Trait-Implementierer gibt - wenn beide #[no_mangle] haben, muss es einen Namenskonflikt geben.

Jetzt ist es einfach, diesen Typ und seine Funktionen aus C zu verwenden:

%Vor%

Dieses Programm kompiliert und funktioniert:

%Vor%

Wenn Methoden akzeptiert &mut self :

%Vor%

Sie müssten const weglassen:

%Vor%

Wenn Methoden akzeptiert self :

%Vor%

Sie müssten die Struktur nach Wert übergeben:

%Vor%

Wenn Sie die Struktur jedoch durch einen undurchsichtigen Zeiger verwenden, kann es schwierig sein, Funktionen aufzurufen, die diesen Wert annehmen, da C die genaue Größe der Struktur kennen muss. Nicht dass es mit undurchsichtigen Zeigern so üblich ist, glaube ich.

    
Vladimir Matveev 07.05.2015, 08:25
quelle
5

Ok, als ich in der akzeptierten Antwort bemerkte, dass ich diesen Ansatz nicht verwenden konnte, endete ich damit, etwas für andere zu kommentieren:

Der Backend-Rost-Code, der nach rlib kompiliert wird:

%Vor%

Der Rost-Wrapper darüber, der auf die obige rlib verweist und in staticlib kompiliert (dh, .a in Linux usw.):

%Vor%

Der C-Wrapper ( api.h & api.c ), der mit der obigen staticlib verknüpft ist und bei Bedarf zu einem gemeinsamen Objekt kompiliert:

%Vor%

Führe jetzt einfach SWIG über die C-Datei (ich habe nur die .c -Datei veröffentlicht - du kannst die .h erraten, über die SWIG läuft) für die Zielsprache, bekomme eine interface_wrap.c generiert ( Standardname) und kompiliert diese Quellcode-Links, die gegen den staticlib gerichtet sind, um ein Shared-Objekt zu erhalten.

ZB für Python:

%Vor%

Rufen Sie jetzt einfach Python an und das Ganze funktioniert:

%Vor%

Ich hoffe, dass jemand das nützlich findet und / oder Verbesserungsvorschläge machen kann. Ich habe dieses Ding auch an meinem github Repo arbeiten lassen: Ссылка

    
ustulation 11.05.2015 10:01
quelle

Tags und Links