Libelektra: Rostbindungen

Erstellt am 28. Mai 2019  ·  45Kommentare  ·  Quelle: ElektraInitiative/libelektra

Ab ca. Mitte Juli möchte ich Rust Bindings für Elektra implementieren.

Ich denke, dass rust-bindgen in der Lage Nach meinem derzeitigen Verständnis und dem Kommentar von elektra-sys Kiste.
Sobald es funktioniert, füge ich eine sichere API in Rust hinzu, damit sie in regulärem Rust verwendet werden kann, ohne dass unsicherer Code aufgerufen werden muss. Dies ist dann die elektra Kiste.
Ich werde dann sicherstellen, dass sie korrekt sind, indem ich mit Ladungstests teste.

Die typische Art, Crates zu dokumentieren, sind Kommentare im Code . docs.rs erstellt die Dokumentation automatisch und macht sie öffentlich verfügbar, daher denke ich, dass es am sinnvollsten ist, die Dokumentation auf diese Weise zu

Um die Kiste auf crates.io zu veröffentlichen , wird ein Konto mit einem API-Token benötigt. Wie mit @markus2330 besprochen , sollte dieses Konto Teil von ElektraInitiative sein, damit es für zukünftige Betreuer zugänglich ist.

Ich werde mir die CMake-Integration zu Beginn des Projekts ansehen, da ich mit CMake im Moment nicht vertraut bin.

Muss ich noch etwas hinzufügen?

Hilfreichster Kommentar

Rust-bindgen bietet zwei Möglichkeiten zum Generieren von Bindungen. Eine erfolgt über die Kommandozeile, was daher ein manueller Vorgang ist und wiederholt werden muss, wenn sich etwas an der C-API ändert. Die andere erfolgt über ein Build-Skript, das jedes Mal ausgeführt wird, wenn Cargo Build ausgeführt wird. Das bedeutet, dass Bindungen bei jedem Build neu generiert werden. Dies wird derzeit umgesetzt. Es erfordert jedoch, dass jeder, der die Bindungen verwendet, über die erforderlichen Header verfügt, die elekra benötigt. Ich kann mir vorstellen, dass wenn jemand elektra gerade installiert, aber nicht kompiliert hat, er möglicherweise nicht alle notwendigen Voraussetzungen erfüllt. Vielleicht ist es sinnvoller, die Header ab und zu manuell neu zu generieren, da sich die C-API nicht mehr stark ändert?

Regeneration bei jedem Build scheint die richtige Lösung zu sein, die anderen Bindungen funktionieren auch so (sie erfordern die Installation von Swig). Sie können die generierten Header-Dateien einfach installieren, um die von Ihnen beschriebenen Probleme zu vermeiden.

Alle 45 Kommentare

Ich weiß nicht so viel über Rust, aber ich nehme an, dass die von rust-bindgen generierten Bindings nur in unsafe Rust? Wenn dies der Fall ist, wäre es schön, einen Wrapper für diejenigen mit einer idiomatischeren Rust-API zu haben.

Die meisten Rust-Bindungen von AFAIK haben eine *-sys Crate für die 1:1-Zuordnung der C-API und eine weitere Crate mit der API, die die meisten Benutzer tatsächlich in Rust verwenden würden. Wenn es eine Möglichkeit gibt, Rust anzuweisen, automatisch keyDel , ksDel und Freunde aufzurufen, wäre das wirklich nett.

Wenn dies der Fall ist, wäre es schön, einen Wrapper für diejenigen mit einer idiomatischeren Rust-API zu haben.

Ja, das ist der Plan. Vergleichen Sie dabei auch mit der C-API und finden Sie vielleicht Verbesserungen in der C-API (zumindest in der Doku).

@PhilippGackstatter Wie besprochen: Bitte https://crates.io/ hochlädt und wie man die Bindung in unser CMake-System einbindet.

@PhilippGackstatter irgendwelche Fortschritte? Wir haben jemanden, der auch daran interessiert sein könnte, die Rust-Bindungen zu erweitern.

@markus2330 Ich habe vor ein paar Tagen angefangen, aber ich habe mich hauptsächlich über bindgen, cmake und wie man es in das Projekt integriert, gelesen, also gab es nichts zu zeigen. Aber ich habe jetzt die ersten paar Dinge fertig (siehe #2826). Ich arbeite jetzt voll an dem Projekt.

Um die Fragen aus #2826 zu beantworten (bitte stellen Sie lieber Fragen in Issues, da PRs dazu neigen, bei Diskussionen, die nicht direkt mit dem Code zu tun haben, verwirrend zu werden):

Eine ist, für welche Header in src/include ich Bindungen generieren muss. Zumindest kdb.h, aber gibt es noch andere, die ich für die Low-Level-API brauche, ohne Plugin-Unterstützung?

Nein, die Low-Level-API ist nur in kdb.h

Die andere ist, muss ich alle Docker-Skripte ändern, um rustup zu installieren (das zum Installieren von cargo und rustc verwendet wird)?

Ja, Sie müssen die Docker-Skripte und möglicherweise auch das Jenkinsfile ändern. Aber Sie müssen nicht alle ändern, wenn Sie für aktuelle Distributionen bauen, reicht es aus.

Es wäre schön, wenn Sie es auch mit dem in Debian Buster kompilierten nativen Rost kompilieren könnten. Die Docker-Datei von Debian Buster ist noch nicht zusammengeführt #2819

Ich vermute, es gibt keine automatisierte Möglichkeit, dies zu tun.

Dazu gibt es einige Ideen: #730

Rust-bindgen bietet zwei Möglichkeiten zum Generieren von Bindungen. Eine erfolgt über die Kommandozeile, was daher ein manueller Vorgang ist und wiederholt werden muss, wenn sich etwas an der C-API ändert. Die andere erfolgt über ein Build-Skript, das jedes Mal ausgeführt wird, wenn Cargo Build ausgeführt wird. Das bedeutet, dass Bindungen bei jedem Build neu generiert werden. Dies wird derzeit umgesetzt. Es erfordert jedoch, dass jeder, der die Bindungen verwendet, über die erforderlichen Header verfügt, die elekra benötigt. Ich kann mir vorstellen, dass wenn jemand elektra gerade installiert, aber nicht kompiliert hat, er möglicherweise nicht alle notwendigen Voraussetzungen erfüllt. Vielleicht ist es sinnvoller, die Header ab und zu manuell neu zu generieren, da sich die C-API nicht mehr stark ändert?

Regeneration bei jedem Build scheint die richtige Lösung zu sein, die anderen Bindungen funktionieren auch so (sie erfordern die Installation von Swig). Sie können die generierten Header-Dateien einfach installieren, um die von Ihnen beschriebenen Probleme zu vermeiden.

Ja, das ist der Plan. Vergleichen Sie dabei auch mit der C-API und finden Sie vielleicht Verbesserungen in der C-API (zumindest in der Doku).

Bisher habe ich einige kleine Verbesserungsmöglichkeiten gefunden

  • keyGetBinary : Als Aufrufcode kann ich nicht wissen, ob ein Rückgabewert von -1 maxSize is 0 oder type mismatch oder etwas anderes bedeutet. Da Rust in seinen Rückgabeargumenten eine explizite Fehlerbehandlung verwendet, möchte ich in der Lage sein, Typkonflikte mit einem Fehler und "maxSize-bezogene" Fehler mit einem anderen zu vergleichen. Aber derzeit muss ich einen allgemeineren Fehler verwenden. Ich könnte selbst nach einem Typkonflikt suchen, aber keyGetBinary tut dies, also habe ich dieselbe Prüfung zweimal.
    keySetName macht etwas Ähnliches und gleicht zwei verschiedene Fehler mit -1 ab. In beiden Fällen gibt es Fehler, die Bugs sind (ungültiger Name) und Fehler, die in Soundprogrammen auftreten können (Schlüssel bereits im Keyset), sodass ich die Entscheidung einigermaßen nachvollziehen kann. Aber warum nicht -2 für Explizitheit und Vermeidung von Doppelprüfungen verwenden?
  • Sollte keyIsDirectBelow grammatikalisch nicht keyIsDirectlyBelow 🙂 sein? Wenn ja, sollte ich dies in der Rust-API korrigieren?

Noch eine Frage: keyRel ist in den CPP-Bindungen nicht implementiert. Soll ich das in Rust auch weglassen?

Tolle Arbeit, aus deinen Fragen ist ersichtlich, dass du schon tief in die API geschaut hast.

Ich könnte selbst nach einem Typkonflikt suchen, aber keyGetBinary tut dies, also habe ich die gleiche Überprüfung zweimal.

Vielleicht können Sie sogar das Typsystem verwenden, um falsche Aufrufe zu vermeiden? (keyGetBinary ist nur für Binärschlüssel zulässig)

Aber warum nicht -2 für Explizitheit und Vermeidung von Doppelprüfungen verwenden?

Der Grund war die Kompatibilität: Die APIs gaben zunächst nur -1 zurück und es ist nicht möglich, andere Fehlercodes hinzuzufügen, ohne vorhandene Programme zu beschädigen (die möglicherweise ==-1 , um auf Fehler zu überprüfen). Aber mit dem nächsten Release (0.9) können wir die API wieder brechen. Und wir könnten das Kompatibilitätsproblem vermeiden, indem wir sagen, dass alle Werte unter 0 Fehler anzeigen. Ich stimme voll und ganz zu, dass Bindungen genaue Fehler liefern sollten.

Möchten Sie diese API-Probleme beheben?

Wenn ja, sollte ich dies in der Rust-API korrigieren?

Die APIs sollten sich in der Schreibweise nicht unterscheiden. Wenn wir es beheben, sollten wir es in der C-API und allen Bindungen beheben (eigentlich müssen nur Java und Go von Hand angepasst werden, die anderen werden sowieso korrekt neu generiert).

keyRel ist in den CPP-Bindungen nicht implementiert. Soll ich das in Rust auch weglassen?

Ja, wie Sie vielleicht schon bemerkt haben, haben keyIs(Direct)Below und keyRel überlappende Funktionen. Die Idee von keyRel war, die API klein zu halten (und damit die Bibliothek klein zu halten). Aber keyRel as-is ist unbrauchbar und auch langsam. Daher werden wir es höchstwahrscheinlich innerhalb von 0.9 entfernen. Siehe doc/todo/FUTURE für andere zu entfernende Kandidaten.

Vielleicht können Sie sogar das Typsystem verwenden, um falsche Aufrufe zu vermeiden? (keyGetBinary ist nur für Binärschlüssel zulässig)

Das ist eine großartige Idee. Ich könnte BinaryKey und StringKey und nur die erste hätte eine get_binary() Methode und nur die zweite eine get_string() Methode und so weiter. Ich werde das prüfen.

Möchten Sie diese API-Probleme beheben?

Ich kann das machen. Kommt darauf an, was für mich Priorität haben soll. Nachdem Sie die sichere API für Rust fertiggestellt hatten, sagten Sie, es wäre schön, auch die Plugin-API in Rust zu haben. Sie können entscheiden, was wichtiger ist.

Das ist eine großartige Idee. Ich könnte BinaryKey und StringKey haben und nur die erste hätte eine get_binary()-Methode und nur die zweite eine get_string()-Methode und so weiter. Ich werde das prüfen.

Danke schön. Es könnte zu viele Würfe erfordern, also lassen Sie uns sehen, ob es eine gute Idee ist. Auch ein anderer Typ könnte für Schlüssel in Keysets nützlich sein (wo setName nicht zulässig ist).

Ich kann das machen. Kommt darauf an, was für mich Priorität haben soll. Nachdem Sie die sichere API für Rust fertiggestellt hatten, sagten Sie, es wäre schön, auch die Plugin-API in Rust zu haben. Sie können entscheiden, was wichtiger ist.

Ja, zuerst die Rust-API von kdb.h fertigstellen und dann sehen wir, wie viele Stunden wir noch aufwenden müssen.

IMO sollte die Rust-Bindung (und jede andere Bindung) zwei Versionen haben. Eine, die die C-API so gut wie möglich widerspiegelt, und eine andere, die idiomatischer für die Sprache ist, die auf der ersten Version aufbaut. In der idiomatischen Version ist es wahrscheinlich eine gute Idee, das Typsystem mit BinaryKey und StringKey (oder sogar Generika) zu verwenden, wenn es die Verwendung der API von Rust erleichtert.

@kodebach Ich stimme zu. Und das scheint auch bei den elektra- und elektra-sys-Kisten zu geschehen.

@kodebach Ich stimme zu. Und das scheint auch bei den elektra- und elektra-sys-Kisten zu geschehen.

Ja glaube ich auch. Wenn die sichere Rust-API Einschränkungen hat, die umgangen werden müssen, kann man elektra_sys importieren und die Eins-zu-Eins-C-Bindungsfunktion direkt aufrufen.

Danke schön. Es könnte zu viele Würfe erfordern, also lassen Sie uns sehen, ob es eine gute Idee ist. Auch ein anderer Typ könnte für Schlüssel in Keysets nützlich sein (wo setName nicht zulässig ist).

Bei der Schlüsselimplementierung hat es super geklappt. Bei KeySets bin ich jedoch auf eine Straßensperre gestoßen. Alle Methoden, die einen Schlüssel zurückgeben, müssen der von mir erstellten gemeinsamen Schnittstelle entsprechen. Ich habe eine Methode get_value implementiert, die einen generischen Rückgabeparameter hat. Bei BinaryKeys sind das Bytes, bei StringKeys sind es Strings. Aber was gibt die Rostversion von ksNext jetzt zurück? Ein Objekt, das die "Schlüsselschnittstelle" erfüllt, aber mit welchem ​​Wert? Ich muss einen auswählen.
So muss die Signatur aussehen, wobei Value der Typ ist, den get_value zurückgibt. Ich kann nur entweder Bytes ( Vec<u8> ) oder String angeben.
pub fn next(&mut self) -> Box<dyn WriteableKey<Value = Vec<u8>>>;

So könnte ich es zu Bytes vereinheitlichen, aber dann muss der Benutzer selbst in String konvertieren. Da der einzige Unterschied zwischen StringKey und BinaryKeys ihre Implementierung von set_value und get_value , würde diese Änderung diese Deutlichkeit entfernen und ich habe im Grunde wieder nur Keys.

Ich denke, das eigentliche Problem besteht darin, dass KeySet in der aktuellen Implementierung nicht explizit sagt, welche Art von Schlüsseln es enthält, aber die *Schlüssel sind es. Aber zuzulassen, dass eine Instanz von KeySet nur StringKey oder BinaryKey enthält, ist meiner Meinung nach eine zu große Einschränkung.
Ich denke, entweder müssen sowohl Key als auch KeySet explizit angeben, was sie enthalten, oder keines von ihnen. Ich tendiere jetzt zu generischen Key und KeySet, nur um mit dem Rest von Elektra konsistent zu sein.
Irgendwelche Gedanken?

Aus Usability-Sicht wäre es sinnvoll, den Key zurückzugeben, der einen Getter für einen String hat, da dies die am häufigsten verwendete Variante ist. Setter für den Namen sollte (wenn möglich) deaktiviert werden, da wir bereits wissen, dass dieser Schlüssel (von next zurückgegeben) Teil eines KeySets ist.

Im Allgemeinen sollte das Typsystem den Benutzer unterstützen und nicht behindern. Also halte es so einfach wie möglich. Die häufigsten Fehler sind:

  1. versuchen, den Schlüsselnamen für einen Schlüssel zu ändern, der sich in einem Schlüsselsatz befindet.
  2. versuchen, Metadatenschlüssel (oder andere const-Schlüssel) zu ändern.
  3. verwirrende Duplizierung von Key/KeySet und Verweise darauf.
  4. Iteration über KeySets, die auch zum Ausschneiden von Schlüsseln verwendet werden, so dass die Iteration nicht mehr korrekt funktioniert.
  5. vergessen einen Key/KeySet freizugeben

Wenn also das Typensystem da helfen kann, wäre es toll. 5. wird hoffentlich nicht durch Design möglich sein, für 1. und 2. sollte deine Abstraktion helfen.

Die Binär-/String-Verwechslung ist eigentlich ein eher seltener Fehler (da Binärschlüssel sehr untypisch sind: Sie werden meistens verwendet, um Funktionszeiger zu halten).

Übrigens. Wenn Sie eine Designentscheidung über die sichere Verwendung von APIs schreiben möchten, fahren Sie bitte fort (doc/decision)

Aus Usability-Sicht wäre es sinnvoll, den Key zurückzugeben, der einen Getter für einen String hat, da dies die am häufigsten verwendete Variante ist.

Aber nicht jede Bytesequenz ist gültiges UTF-8, also wäre das nicht mehr wirklich typsicher, oder?

AFAIK, das Makrosystem in Rust ist sehr mächtig, vielleicht gibt es eine Möglichkeit, eine Funktion zu schreiben, die immer den richtigen Typ zurückgibt. In Kotlin gibt es beispielsweise eine Technik für Maps, um den Werttyp im Schlüssel zu codieren. Die API-Referenz hier ist ein Beispiel.

Alternativ kann ein StringKeySet sinnvoll sein, das nur StringKey s akzeptiert, da Binärschlüssel so selten sind und in Konfigurationen meist nicht verwendet werden.

Aus Usability-Sicht wäre es sinnvoll, den Key zurückzugeben, der einen Getter für einen String hat, da dies die am häufigsten verwendete Variante ist. Setter für den Namen sollte (wenn möglich) deaktiviert werden, da wir bereits wissen, dass dieser Schlüssel (von next zurückgegeben) Teil eines KeySets ist.

Aber es ist immer noch möglich, wenn auch selten, ein KeySet mit gemischten Schlüsseln zu haben. Dann wäre es ein Fehler, immer einen StringKey zurückzugeben und get_string aufzurufen, aber das Typsystem lässt dies nicht nur zu, sondern führt Sie auch dorthin, da es für diesen Typ keine Methode get_binary .

Zuvor schlage ich vor, KeySet generisch zu machen und es als KeySet<StringKey> instanziieren, wenn der Benutzer sicher ist, dass nur StringKeys drin sind (für diese KeySets, die nicht von Rust stammen). Dann ist es nur natürlich, dass eine Iteration darüber nur StringKeys produzieren würde.
Es würde auch erzwingen, dass KeySets über das Typsystem homogen sind, zumindest die von Rust-Benutzern erstellten, was insgesamt sicherer wäre.
In seltenen Fällen, in denen ein Binärschlüssel erwartet wird, müsste der Benutzer mit is_binary und is_string prüfen und dann konvertieren, was ein sicherer Methodenaufruf wäre.

verwirrende Duplizierung von Key/KeySet und Verweise darauf.

Ich denke, das einzige, was ich tun kann, ist, die Verwendung von Duplikaten anstelle von Ref-Zählungen zu fördern. Es könnte für die Leistung schlechter sein, aber keyDel wird automatisch von Rust aufgerufen, während das Zählen von Refs vollständig manuell erfolgt. Duplizieren ist also sicherlich einfacher als das Zählen von Schiedsrichtern.

Iteration über KeySets, die auch zum Ausschneiden von Schlüsseln verwendet werden, so dass die Iteration nicht mehr korrekt funktioniert.

Meinst du das Ändern des Keysets während der Iteration darüber?

Übrigens. Wenn Sie eine Designentscheidung über die sichere Verwendung von APIs schreiben möchten, fahren Sie bitte fort (doc/decision)

Was wäre der Inhalt davon?

AFAIK, das Makrosystem in Rust ist sehr mächtig, vielleicht gibt es eine Möglichkeit, eine Funktion zu schreiben, die immer den richtigen Typ zurückgibt.

Ich denke, dass das "aktuelle" Design von KeySet, das alles und konkrete Key-Typen enthalten kann, nicht zusammenarbeitet, zumindest nicht gut. Aber ich werde mir Makros anschauen.

Aber nicht jede Bytesequenz ist gültiges UTF-8, also wäre das nicht mehr wirklich typsicher, oder?

Weder die Strings noch der Binärwert von Elektra müssen UTF-8 sein. Elektra entscheidet nur zwischen String und Binär (kann 0 Byte enthalten).

AFAIK, das Makrosystem in Rust ist sehr mächtig, vielleicht gibt es eine Möglichkeit, eine Funktion zu schreiben, die immer den richtigen Typ zurückgibt. In Kotlin gibt es beispielsweise eine Technik für Maps, um den Werttyp im Schlüssel zu codieren. Die API-Referenz hier ist ein Beispiel.

Wir müssen auch aufpassen, dass wir uns um nützliche Funktionen bemühen. Binäre Schlüssel sind selten.

Alternativ kann ein StringKeySet sinnvoll sein, das nur StringKeys akzeptiert, da Binärschlüssel so selten sind und in Konfigurationen meist nicht verwendet werden.

Ja, aber ich würde StringKeySet als das normale KeySet sehen.

Aber es ist immer noch möglich, wenn auch selten, ein KeySet mit gemischten Schlüsseln zu haben. Dann wäre es ein Fehler, immer einen StringKey zurückzugeben und get_string aufzurufen, aber das Typsystem lässt dies nicht nur zu, sondern führt Sie auch dorthin, da es für diesen Typ keine get_binary-Methode gibt.

Ja, aber wie gesagt, das ist ein kleines Problem. Leute, die Binärdaten (wie Funktionsadressen) speichern, werden herausfinden, wie der Schlüssel umgewandelt wird (wenn es eine Dokumentation dazu gibt).

Zuvor schlage ich vor, KeySet generisch zu machen und als KeySet zu instanziierenwenn der Benutzer sicher ist, dass nur StringKeys drin sind (für diese KeySets, die nicht von Rust stammen). Dann ist es nur natürlich, dass eine Iteration darüber nur StringKeys produzieren würde.

Es wäre nur eine vorgetäuschte Sicherheit, da KeySets von KDB (extern) stammen und auf jeden Fall Binärdaten enthalten könnten. Daher bevorzuge ich KeySet nicht generisch.

Wenn Sie mit Generika herumspielen möchten, stellen Sie Getter und Setter bereit, die KeySets in (generische) Datenstrukturen konvertieren. ZB ein Elektra-Array von ganzen Zahlen zu Vec<i32> .

Meinst du das Ändern des Keysets während der Iteration darüber?

Ja cut ändert das KeySet. Im Allgemeinen ist dies mit den Iteratoren sicher, aber viele Leute haben Probleme, es richtig zu machen.

Was wäre der Inhalt davon?

Eine Zusammenfassung dessen, was wir hier besprechen und wie Sie es entworfen haben.

Ich denke, dass das "aktuelle" Design von KeySet, das alles und konkrete Key-Typen enthalten kann, nicht zusammenarbeitet, zumindest nicht gut.

Ich stimme zu.

Aber ich werde mir Makros anschauen.

Bitte nicht priorisieren.

Weder die Strings noch der Binärwert von Elektra müssen UTF-8 sein.

Dann sollten wir nach einer Schnellsuche OsString oder CString anstelle von String .

Weder die Strings noch der Binärwert von Elektra müssen UTF-8 sein.

Dann sollten wir nach einer Schnellsuche OsString oder CString anstelle von String .

Im Moment konvertiere ich zwischen Rusts String (das ist UTF-8) in ein CString bevor ich es an elektra weitergebe. Der Grund dafür ist, dass String der Standardstring ist und die meisten anderen Bibliotheken erwarten, damit zu arbeiten.
Ich kann stattdessen die High-Level-API veranlassen, CString s anzufordern und zurückzugeben, sodass der Benutzer sich mit dem Conversion-Code befassen müsste, wenn er ein String . Es würde zu einer dünneren API und weniger Fehlerbehandlung führen, die behandelt werden muss. Ich nehme an, es kommt darauf an, wie die meisten Benutzer die API verwenden möchten, in die ich nicht so viel Einblick habe.

Ich stimme zu, dass es am besten ist, den gebräuchlichsten String-Typ der Sprachen zurückzugeben. Nicht-UTF8-Strings sollten selten sein (vielleicht sogar seltener als Binärdateien).

Ich stimme zu, dass es am besten ist, den gebräuchlichsten String-Typ der Sprachen zurückzugeben. Nicht-UTF8-Strings sollten selten sein (vielleicht sogar seltener als Binärdateien).

Ich versuche herauszufinden, wie man am besten mit der Richtung Rust -> C umgeht, von UTF-8 zu einer C-Saite. UTF-8-Strings dürfen null Byte enthalten, aber der einzige Codepunkt, an dem dies erscheint, ist das NUL-Zeichen, andernfalls nicht . Ich denke, es wäre vernünftig, dies als Vorbedingung in der Bindungsdokumentation anzugeben, dass die Strings das Null-Byte nicht enthalten dürfen. Wenn dies trotzdem der Fall ist, gerät der Code an diesem Punkt in Panik.

Die andere Möglichkeit besteht darin, einen Fehler von allen eingestellten Funktionen zurückzugeben, die einen String akzeptieren. Aber dann müssen sich die Benutzer die ganze Zeit mit diesem NulError herumschlagen und es wird praktisch nie zurückgegeben.

keyNew kann bei einem Zuordnungsfehler einen NULL-Zeiger zurückgeben. In Rust kann ich entweder explizite Fehler oder Panik zurückgeben, aber keine implizite Null. Der Rost Dokument auf Signalisierungsfehler hält einen katastrophalen Fehler des Gedächtnisses und die stdlib Abbruch s in diesem Fall. Die Java-Bindung scheint diesen Fall nicht zu verarbeiten, daher gehe ich davon aus, dass sie den Prozess ebenfalls beenden würde, da ein NullPointerException geworfen wird.
Sind Sie der Meinung, dass es am besten ist, hier Panik aufzurufen (Abbruch ermöglicht keine Ausführung von Destruktoren)?

Ich denke, es wäre vernünftig, dies als Vorbedingung in der Bindungsdokumentation anzugeben, dass die Strings das Null-Byte nicht enthalten dürfen. Wenn dies trotzdem der Fall ist, gerät der Code an diesem Punkt in Panik.

Ja, ist vernünftig.

Sind Sie der Meinung, dass es am besten ist, hier Panik aufzurufen (Abbruch ermöglicht keine Ausführung von Destruktoren)?

Ja, es ist sinnvoll, in Panik zu geraten, wenn ein Malloc fehlgeschlagen ist. (Im Fall von Rust würde die stdlib dasselbe tun. In C bricht die stdlib nicht ab, also bricht C-Elektra auch nicht ab).

Nachdem die Rust-Anbindungen nun in master zusammengeführt wurden, möchte ich sie auf crates.io veröffentlichen.
Ich schlage vor, sie mit der Version zu veröffentlichen, die auf (Standard) 0.1.0 , anstatt sie an Elektra zu binden, einfach weil die Reife der Bindungen und Elektra selbst unterschiedlich sind. Stimmen Sie @markus2330 zu?

Für die Veröffentlichung auf https://crates.io ist ein GitHub-Konto erforderlich. Das Eigentum an Kisten kann zwischen Konten übertragen werden, sodass ich vorerst meine eigenen verwenden kann. Oder jemand anderes könnte sich anmelden und mir das API-Token senden, das für die Veröffentlichung erforderlich ist.

Vielen Dank für die Veröffentlichung auf crates.io :sparkle:

Ich würde die Version direkt an Elektra binden, da sie Teil von Elektras Repos sind. Aber es ist nicht wirklich wichtig: Wenn crates.io normalerweise bestimmte Versionsschemata hat, bleiben Sie besser bei dem, was dort üblich ist.

Oder jemand anderes könnte sich anmelden und mir das API-Token senden, das für die Veröffentlichung erforderlich ist.

Ich habe mich autorisiert eingeloggt. Ich schicke Ihnen das API-Token.

Ich würde die Version direkt an Elektra binden, da sie Teil von Elektras Repos sind. Aber es ist nicht wirklich wichtig: Wenn crates.io normalerweise bestimmte Versionsschemata hat, bleiben Sie besser bei dem, was dort üblich ist.

Das Hauptproblem dabei ist laut semantischer Versionierung, wenn wir eine Breaking Change in den Bindings vornehmen müssen, können wir die Version nicht einfach entsprechend aktualisieren. Wir konnten also nur bahnbrechende Änderungen vornehmen, wenn Elektra sie macht.

Gemäß der semantischen Versionierung können Sie alle wichtigen Änderungen vornehmen, solange die Version mit 0 beginnt. Wenn wir Elektra 1.0 es unser Interesse auch die Bindungen stabil zu halten. Und selbst wenn uns das nicht gelingt, haben wir in Zukunft auch die Möglichkeit, die Versionen unabhängig zu machen (einfach die Major-Version der Rust-Bindung erhöhen). Daher denke ich, dass es sicher ist, jetzt einfach die Version von Elektra zu verwenden.

Du hast Recht, ich habe nicht daran gedacht, die Hauptversionen später zu erhöhen.

Im Moment gibt wrapper.h #include "kdb.h" an, um den kdb-Header einzuschließen und Bindungen dafür zu generieren. Aber clang findet den Header nicht (zum Beispiel in ubuntu:18.10 ). Also muss ich clang explizit sagen, dass es /usr/include/elektra einschließen soll, damit es erstellt wird.
Wird elektra immer in /usr/include/elektra installiert, damit diese Lösung für die meisten Distributionen funktionieren sollte?

Wird elektra immer in /usr/include/elektra installiert, damit diese Lösung für die meisten Distributionen funktionieren sollte?

Ja, denn es gibt eine andere Bibliothek (ich glaube von Kerberos), die /usr/include/kdb.h .

Momentan muss /usr/include/elektra Teil des Include-Pfads sein, aber AFAIK wollen wir das so ändern, dass stattdessen #include <elektra/kdb.h> verwendet werden kann.

Wird elektra immer in /usr/include/elektra installiert, damit diese Lösung für die meisten Distributionen funktionieren sollte?

Standardmäßig ist es /usr/local/include/elektra, aber die meisten Distributionen verwenden /usr/include/elektra, aber es gibt keine Garantie. Aus diesem Grund bieten Build-Systeme normalerweise eine gewisse Unterstützung zum Auffinden von Header-Dateien. Elektra unterstützt cmake und pkg-config.

Können Sie etwas Kontext geben, wo Sie dies benötigen?

kann stattdessen verwendet werden.

muss stattdessen verwendet werden. Der relevante PR ist #2880

Der Wechsel zu #include <elektra/kdb.h> funktioniert definitiv in Ubuntu. Also wechsle ich zu diesem Pfad, anstatt /usr/include/elektra .

Der Wechsel zu #include <elektra/kdb.h> funktioniert definitiv in Ubuntu. Also wechsle ich zu diesem Pfad, anstatt /usr/include/elektra .

Es wird wahrscheinlich nicht für alle Header funktionieren, einige verlassen sich darauf, dass /usr/include/elektra im Include-Pfad enthalten ist.

Wahrscheinlich das Beste (wenn es für Sie möglich ist) wäre pkg-config oder cmake --find-package zu verwenden, um die Elektra-Dateien zu finden (IMO cmake funktioniert besser).

Können Sie etwas Kontext geben, wo Sie dies benötigen?

Wenn ein Nutzer also Elektra auf seiner Maschine kompiliert, dann braucht er nur noch Rost/Ladung und kann die Bindungen nutzen. Aber der andere Anwendungsfall, für den crates.io verwendet werden sollte, ist, wenn jemand Elektra (und Header) über seinen Paketmanager installiert. Dann sind die Bibliothek und die Header verfügbar. Jetzt nimmt dieser Benutzer elektra in seine Abhängigkeiten auf und cargo holt die elektra-sys Kiste. Es verlässt sich nur auf das Build-Skript und den Clang, um die Bindungen zu generieren. Aber Clang muss irgendwie kdb.h . Ich kann also entweder zusätzliche hartcodierte Include-Pfade im Build-Skript übergeben oder die #include ... Anweisung direkt ändern.

Wahrscheinlich das Beste (wenn es für Sie möglich ist) wäre pkg-config oder cmake --find-package zu verwenden, um die Elektra-Dateien zu finden (IMO cmake funktioniert besser).

Ich kann versuchen, pkg-config oder cmake als Build-Abhängigkeit hinzuzufügen und kdb.h diese Weise

Ja, Sie können versuchen, pkg-config in Ihrem Build-Skript aufzurufen. Wenn pkg-config nicht verfügbar ist, können Sie hartcodierte Pfade wie /usr/include/elektra und /usr/local/include/elektra ausprobieren. (Wenn crates.io die Verfügbarkeit von pkg-config nicht erfordert.)

Du könntest diese Kiste probieren

Ja, Sie können versuchen, pkg-config in Ihrem Build-Skript aufzurufen. Wenn pkg-config nicht verfügbar ist, können Sie hartcodierte Pfade wie /usr/include/elektra und /usr/local/include/elektra ausprobieren. (Wenn crates.io die Verfügbarkeit von pkg-config nicht erfordert.)

Ich habe pkg-config als optionale Abhängigkeit hinzugefügt. Wenn es hinzugefügt wird, sucht es nach Elektra und verwendet das mitgelieferte mitgelieferte. Andernfalls wird in den beiden von Ihnen benannten Verzeichnissen gesucht.

Die Bindungen sind jetzt erschienen: elektra und elektra-sys :smiley:

Aufgrund der fehlenden Systemabhängigkeit von libelektra in der docs.rs-Buildumgebung wurde die Dokumentation nicht erstellt. Außerdem werden sie am 30. September die Build-Umgebung ändern.
Ich habe eine Anfrage gestellt , libelektra als Abhängigkeit hinzuzufügen, damit es am 30. September korrekt erstellt wird. Er fügte das Paket auch der bestehenden Umgebung hinzu, sodass die Dokumente jetzt verfügbar sind :+1:

Ich denke, nachdem #2980 zusammengeführt wurde, kann dieses Problem geschlossen werden.

Sehr nett, sie haben superschnell reagiert. Wird es ein Problem sein, dass sie es mit einer ziemlich alten Libelektra bauen? (Ich habe nicht überprüft, welche Version, aber wenn sie vom Paketmanager aufgenommen werden, ist sie definitiv älter als 0.9.)

Keine Probleme für die elektra Kiste, da es sich nur um eine Dokumentation handelt. elektra-sys Ich denke, es enthält die Version von elektra, für die es generiert wurde, anstelle der aktuellen. Aber ich denke, kaum jemand würde die rohen Bindungen anstelle der Wrapper verwenden. Also ein kleiner Kompromiss für die automatische Erstellung von Dokumenten.

Können Sie dann die Links zur Doku in unserem Repo hinzufügen?

elektra-sys scheint sowieso fast unbrauchbar zu sein. Es zeigt Hunderte von Symbolen, die nichts/wenig mit Elektra zu tun haben. Außerdem gibt es keine Doku zu den einzelnen Funktionen, zB

https://docs.rs/elektra-sys/0.9.0/elektra_sys/fn.keyString.html

Können Sie dann die Links zur Doku in unserem Repo hinzufügen?

Ja, ich werde es dem bestehenden PR hinzufügen

elektra-sys scheint sowieso fast unbrauchbar zu sein. Es zeigt Hunderte von Symbolen, die nichts/wenig mit Elektra zu tun haben.

Ich werde das prüfen.

Außerdem gibt es keine Doku zu den einzelnen Funktionen, zB

Es ist typisch für -sys-Kisten, dass sie keine docu haben (zum Beispiel openssl-sys ), da es sich um eine Eins-zu-Eins-Übersetzung des C-Äquivalents handelt. Man muss also direkt im C-Dokument nachschlagen. Ich müsste auch alle Dokumente von Hand kopieren, was einen weiteren Wartungsaufwand hinzufügt. Ich kann jedoch auf der Hauptseite der Dokumentation auf https://doc.libelektra.org/api/current/html/index.html verlinken.

elektra-sys scheint sowieso fast unbrauchbar zu sein. Es zeigt Hunderte von Symbolen, die nichts/wenig mit Elektra zu tun haben.

Ich werde das prüfen.

Es ist in #2980 behoben und wird auf docs.rs behoben, wenn wir das nächste Mal die Kiste veröffentlichen.

Ich kann jedoch auf der Hauptseite der Dokumentation auf https://doc.libelektra.org/api/current/html/index.html verlinken.

Ja, gute Idee!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

e1528532 picture e1528532  ·  4Kommentare

markus2330 picture markus2330  ·  3Kommentare

dominicjaeger picture dominicjaeger  ·  3Kommentare

markus2330 picture markus2330  ·  4Kommentare

mpranj picture mpranj  ·  3Kommentare