Erstellen einer statischen C-Struktur mit Strings

8

Ich versuche, eine dynamische Bibliothek in Rust zu erstellen, die eine Struktur als ein Symbol exportiert, das über dlopen () in ein C-Programm geladen wird.

Allerdings habe ich beim Zugriff auf die zweite Zeichenfolge in der Struktur einige segfaults gefunden, also habe ich ein kleines Testprogramm erstellt, um herauszufinden, was ich falsch mache.

Dies ist der Rust-Code (test.rs), zusammengestellt mit "rustc --crate-type dylib test.rs":

%Vor%

und hier ist das C-Programm, das versucht, die Bibliothek zu laden (test.c), kompiliert mit "gcc test.c -ldl -o test":

%Vor%

Dies ist die Ausgabe:

%Vor%

Wie Sie sehen, ist die Adresse der Desc- & gt; -Version tatsächlich 0xc (12), was der Länge der ersten Zeichenkette entspricht. Es sieht also so aus, als ob die Struktur, die in die Bibliothek gepackt wird, auch die Stringlänge nach der Speicheradresse enthält.

Benutzt ich hier den falschen String-Typ? Wie Sie sehen können, musste ich auch die Strings NULL manuell beenden lassen. Ich habe versucht, den CString-Wrapper zu verwenden, aber das scheint in diesem Fall nicht zu funktionieren ("statische Elemente dürfen keine Destruktoren haben").

Ich habe jeden Abend das neueste Rust unter Linux:

%Vor%     
chrippa 16.09.2014, 23:38
quelle

2 Antworten

2

Das Layout eines Slices ( &[T] oder &str ) ist ein Zeiger gefolgt von einer Länge, wie von die Slice struct des Moduls std::raw . Aus diesem Grund zeigt das Lesen des version -Feldes aus Ihrem C-Code die Länge des Wertes name an. (Beachten Sie jedoch, dass das genaue Speicherlayout von Slices nicht als stabil betrachtet wird, sodass es sich in einer späteren Version ändern kann. In jedem Fall sollten not Rust-spezifische Datentypen nur an C übergeben; primitive Typen übergeben - einschließlich roher Zeiger - und typisierte Typen mit #[repr(C)] .)

BEARBEITEN: Leider gibt es momentan in Rust keine Möglichkeit, das zu tun. Es gibt Funktionen, um rohe Zeiger von Slices zu erhalten, aber Funktionsaufrufe sind in statischen Initialisierern nicht erlaubt . Wie von sellibitze in den Kommentaren vorgeschlagen, sollten Sie diese Variable in einer C-Quelldatei definieren.

    
Francis Gagné 17.09.2014, 00:10
quelle
3

Die kurze Antwort ist, dass Sie eine solche Struktur nicht statisch zuordnen können. Future Rust wird wahrscheinlich diese Fähigkeit erlangen.

Was Sie tun können, ist, dass Sie eine Struktur statisch zuweisen, die Nullzeiger enthält, und diese Nullzeiger auf etwas Nützliches setzen, wenn Sie die Funktion aufrufen. Rust hat static mut . Es erfordert unsafe code , ist gar nicht threadsafe und wird (nach bestem Wissen und Gewissen) als Code-Geruch betrachtet.

Genau hier halte ich es für eine Umgehung der Tatsache, dass es keine Möglichkeit gibt, ein &[T] in ein statisches *const T zu verwandeln.

%Vor%

Antwort kopiert von der doppelten Frage

    
oli_obk - ker 10.07.2015 14:58
quelle

Tags und Links