2016-05-29 30 views
2

Ich habe eine gemeinsam genutzte Bibliothek erstellt, die ein Array von Strings oder nur einen String als Funktionsparameter verwendet. Ich verwende den eingebauten "string" -Typ, der in der D-Sprache kommt. Ich habe die Bibliothek in einer anderen D-Anwendung getestet, die Bibliothek funktioniert. Für GUI benutze ich Lazarus, und das Problem ist, dass ich Pascals Strings nicht durch die Library identifizieren kann.Senden/Empfangen von Zeichenfolgen und Arrays zwischen D 'Shared Library und Pascal (Lazarus) Host

Ich verwende den AnsiString-Typ in Pascal, und ich glaube, dass die Standardcodierung in D auch ANSI ist. Wenn ein String-Array an D gesendet wurde, wird es komplett durcheinander gebracht. In Pascal setze ich seine Länge auf 1, aber mit dem Debugger finde ich, dass es in der Bibliothek "3086778472" wird. Aber das ist nicht alles t, wenn dieser Code in der Bibliothek ausgeführt wird:

line=<recieved-array-of-string's-name>[0]; 

Es bewirkt eine ‚Außen: SIGSEGV‘. Ich habe keine Ahnung, was dieser Fehler bedeutet.

Meine Frage hier ist: Wie konvertiere ich eine D-Zeichenfolge in eine Pascal und dann wieder zurück, und das gleiche mit Arrays?

EDIT: Ich habe versucht Eugen Riecks Lösung, es funktioniert nicht. Ich denke, das Problem ist nicht das; Ich habe eine andere Bibliothek in D mit einer Funktion erstellt, die nur eine Zahl (Datentyp = Ubyte) zurückgibt, aber das funktioniert auch nicht.

EDIY2: Weiter verfolgt das Problem, ich habe festgestellt, dass die Bibliothek die Parameter nicht korrekt empfängt.

+0

Seien Sie vorsichtig nicht nur mit Strings, sondern auch mit dynamisch zugewiesenen Arrays. –

+0

Sieht aus, als würden Ihre Aufrufkonventionen nicht übereinstimmen. –

Antwort

1

Der einfachste Weg, um Strings herumzugeben (während mit Abstand das technisch schlechteste) ist die alte C-Style 0-terminierte Version. Dies funktioniert "gut genug" für menschenlesbare Strings.

auf der D-Seite: toStringz() und fromStringz() wandeln zwischen einer D-Saite und einem C-String

Auf der Seite, FP: Die Familie der PChar fucntions bietet für C strings Unterstützung.

+0

Sind die Strings in einem Array, muss ich sie mit toStringz einzeln umwandeln oder gibt es bereits eine Funktion? – Nafees

+0

Und in welchen Modulen sind diese Funktionen? EDIT: fand sie in std.string. – Nafees

+0

@Nafees Die Funktionen - wie Sie gesagt haben - befinden sich in std.string, mir ist keine Array-Funktion bekannt - aber das sollte ziemlich trivial sein, wenn man über 'opApply()' auf einen vom Array abgeleiteten 'Bereich' schreibt. –

2

D Zeichenfolgen sind Pascal Zeichenfolgen.

Ein Schnitt oder dynamisches Array in D ist einfach ein Zeiger (arr.ptr) und eine Länge (arr.length). string, das ist ein Alias ​​von immutable(char)[] ist keine Ausnahme.

Wenn Sie eine D-Zeichenfolge in einige PascalString struct konvertieren müssen, ist eine einfache und effiziente Möglichkeit, den Zeiger und die Länge von der D-Zeichenfolge in die Struktur PascalString zu kopieren. Um von einer PascalString in eine D-Zeichenfolge zu konvertieren, zerschneiden Sie den Zeiger: pascalstring.pointer[0..pascalstring.length]. jedoch

Zwei Dinge zu beachten,:

  • Da D-Strings sind immutable, die PascalString Zeiger muss const char* sein. Wenn dies nicht der Fall ist, müssen Sie eine veränderbare Kopie der Zeichenfolge erstellen (der einfachste Weg ist dup).
  • Wenn Sie die Zeichenfolgen mit D GC-verwaltetem Speicher zuordnen, müssen Sie sicherstellen, dass D's GC die Zeichenfolge finden kann. Andernfalls riskieren Sie, dass der GC die Zeichenfolge während der Verwendung erfasst (D durchsucht den Speicher nicht die C-Bibliotheken verwenden).
+0

Könnten Sie bitte einen Beispielcode hinzufügen, den ich ohne Code nicht verstehen kann. – Nafees