Typen zur Verwendung in Librarys

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Typen zur Verwendung in Librarys

Beitrag von RSE »

Ich habe bisher wenig mit librarys zu tun gehabt, aber ich habe mitbekommen, dass man aus Gründen der C-Kompatibilität nicht jedes Konstrukt einfach als Parameter verwenden sollte. Strings sollte man als PChar übergeben. Wie ist denn die Übliche Vorgehensweise, wenn man einen Array of String zu übergeben hat? String -> PChar, Open Array -> ???
Zuletzt geändert von RSE am Fr 13. Nov 2009, 09:39, insgesamt 1-mal geändert.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: array of string wie für library umbauen?

Beitrag von mschnell »

Da "log string" eine Delphi/FPC Besonderheit sind, kann man sie überhaupt nicht mit C programmen verwenden (außer man will das low-level-Verhalten nachbauen).


Am besten wohl eine TStringlist nehmen und mit SaveToStream in einen Byte-Stream exportieren und dann als array of char nach C übergeben. Oder von C aus eine Funktion aufrufen (z.B. als callback), die einzelne Teilstrings als array of char erzeugt.

-Michael

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: array of string wie für library umbauen?

Beitrag von RSE »

mschnell hat geschrieben:Da "log string" eine Delphi/FPC Besonderheit sind...
Was sind "log string"?
mschnell hat geschrieben:Am besten wohl eine TStringlist nehmen und mit SaveToStream in einen Byte-Stream exportieren und dann als array of char nach C übergeben. Oder von C aus eine Funktion aufrufen (z.B. als callback), die einzelne Teilstrings als array of char erzeugt.
Boah, ist das aufwendig. Gibt es gar keine Open Arrays (kann ich mir kaum vorstellen), oder kann man sowas wie Array of PChar als Parameter benutzen?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Typen zur Verwendung in Librarys

Beitrag von RSE »

Wie stellt man in Librarys sicher, dass die andere Aufrufkonvention (z.B. stdcall) auch bei Events Anwendung findet? Wird das lediglich im Typ des Events so angegeben wie im Beispiel unten?

Code: Alles auswählen

TLogEvt = procedure(Args: array of String {muss noch ersetzt werden}) of Object; stdcall;
 
  IMPlayer = interface
    procedure Log(Args: array of String {muss noch ersetzt werden}); stdcall;
    function GetOnLog: TLogEvt; stdcall;
    procedure SetOnLog(const AValue: TLogEvt); stdcall;
    property OnLog: TLogEvt read GetOnLog write SetOnLog;
  end;
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Typen zur Verwendung in Librarys

Beitrag von marcov »

RSE hat geschrieben:Ich habe bisher wenig mit librarys zu tun gehabt, aber ich habe mitbekommen, dass man aus Gründen der C-Kompatibilität nicht jedes Konstrukt einfach als Parameter verwenden sollte. Strings sollte man als PChar übergeben. Wie ist denn die Übliche Vorgehensweise, wenn man einen Array of String zu übergeben hat? String -> PChar, Open Array -> ???
Array of pchar mit dem letzten element NIL

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Typen zur Verwendung in Librarys

Beitrag von RSE »

Vielen Dank :)
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Typen zur Verwendung in Librarys

Beitrag von theo »

Array of pchar mit dem letzten element NIL
Es gibt in Freepascal Typen PPChar resp. TPCharArray die für sowas gedacht sind.
Ich würde evtl. auch einfach TStringList .Text als PChar übergeben.
Dieser ist dann LineEnding delimitiert (wie ein Textfile) und lässt sich in C auch wieder in ein Array aufsplitten.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Typen zur Verwendung in Librarys

Beitrag von RSE »

PPChar klingt gut. Ich habe sogar in den Sourcen gefunden, wie man damit umgeht:

Code: Alles auswählen

Function PCharListToStrings(P : PPChar; List : TStrings) : Integer;
begin
  List.Clear;
  While P^<>Nil do
    begin
    List.Add(StrPas(P^));
    P:=PPChar(PChar(P)+SizeOf(PChar));
    end;
  Result:=List.Count;
end;
 
Function StringsToPCharList(List : TStrings) : PPChar;
Var
  I : Integer;
  S : String;
begin
  I:=(List.Count)+1;
  GetMem(Result,I*sizeOf(PChar));
  PPCharArray(Result)^[List.Count]:=Nil;
  For I:=0 to List.Count-1 do
    begin
    S:=List[i];
    PPCharArray(Result)^[i]:=StrNew(PChar(S));
    end;
end;
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: array of string wie für library umbauen?

Beitrag von mse »

RSE hat geschrieben:Gibt es gar keine Open Arrays (kann ich mir kaum vorstellen)
Die C-Ellipse kann mit array of const modelliert werden AFAIK:

Code: Alles auswählen

//void test(int par1,...);
procedure test(par1: integer; dotdotdot: array of const); cdecl; external;
, oder kann man sowas wie Array of PChar als Parameter benutzen?
Ja, häufig wird der Schluss des Array mittels NIL-Pointer markiert.

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Typen zur Verwendung in Librarys

Beitrag von marcov »

theo hat geschrieben:
Array of pchar mit dem letzten element NIL
Es gibt in Freepascal Typen PPChar resp. TPCharArray die für sowas gedacht sind.
Ich würde evtl. auch einfach TStringList .Text als PChar übergeben.
Dieser ist dann LineEnding delimitiert (wie ein Textfile) und lässt sich in C auch wieder in ein Array aufsplitten.
Das introduciert Limitationen (keine Lineendings in die Strings) die nicht nötig sind. Würde ich nicht machen

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Typen zur Verwendung in Librarys

Beitrag von RSE »

Ich habs schon mit PPChar umgesetzt, was ja auch laut mse (siehe oben) ein verbreitetes Vorgehen ist. Es klappt sogar auf Anhieb fehlerfrei. :D
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Typen zur Verwendung in Librarys

Beitrag von theo »

marcov hat geschrieben: Das introduciert Limitationen (keine Lineendings in die Strings) die nicht nötig sind. Würde ich nicht machen
Ich kann dir nicht ganz folgen. Wenn ich den Inhalt einer TStringList zurückgeben will, sehe ich da eigentlich kein Probleme.
Kannst du das präzisieren?

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Typen zur Verwendung in Librarys

Beitrag von Hitman »

theo hat geschrieben:
marcov hat geschrieben: Das introduciert Limitationen (keine Lineendings in die Strings) die nicht nötig sind. Würde ich nicht machen
Ich kann dir nicht ganz folgen. Wenn ich den Inhalt einer TStringList zurückgeben will, sehe ich da eigentlich kein Probleme.
Kannst du das präzisieren?
array of string = ['blabla' + #13#10 + 'blubb', 'noch ein zweiter string']

in der stringlist sind jetzt also drei Zeilen
beim Zurückkonvertieren hast du jetzt plötzlich ein array mit drei strings

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Typen zur Verwendung in Librarys

Beitrag von theo »

Hitman hat geschrieben: array of string = ['blabla' + #13#10 + 'blubb', 'noch ein zweiter string']
in der stringlist sind jetzt also drei Zeilen
beim Zurückkonvertieren hast du jetzt plötzlich ein array mit drei strings
Ich sagte "den Inhalt einer TStringList zurückgeben" also TStringList.Text , was du da machst ist was anderes.

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Typen zur Verwendung in Librarys

Beitrag von marcov »

theo hat geschrieben:
marcov hat geschrieben: Das introduciert Limitationen (keine Lineendings in die Strings) die nicht nötig sind. Würde ich nicht machen
Ich kann dir nicht ganz folgen. Wenn ich den Inhalt einer TStringList zurückgeben will, sehe ich da eigentlich kein Probleme.
Kannst du das präzisieren?
Natürlich. s2.text:=s1.text macht s1 nicht gleich an s2, wie das understehendes Programm schaut.

Code: Alles auswählen

uses classes;
 
procedure writestrl(s:tstringlist;title:string);
 
var i : Integer;
begin
  writeln(title,':');
  for i:=0 to s.count-1 do
   writeln(i:5,' ',s[i]);
end;
 
 
var s1,s2 : TStringlist;
 
begin
 s1:=tstringlist.create;
 s2:=tstringlist.create;
 
 s1.add('aaaa');
 s1.add('a'#13#10'a');
 s1.add('b'#13#10'b');
 writeln(s1.text);
 s2.text:=s1.text;
 writestrl(s1,'s1');
 writeln;
 writestrl(s2,'s2');
end.

Antworten