AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein C++ Dll soll Zeichenkette manipulieren
Thema durchsuchen
Ansicht
Themen-Optionen

C++ Dll soll Zeichenkette manipulieren

Ein Thema von rey003 · begonnen am 1. Feb 2009 · letzter Beitrag vom 7. Feb 2009
 
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.570 Beiträge
 
Delphi 12 Athens
 
#9

Re: C++ Dll soll Zeichenkette manipulieren

  Alt 2. Feb 2009, 15:45
ich bin nich so gut in C ... drum hab ich's mal in Delphi gemacht, aber läßt sich bestimmt leicht konvertieren


drei Funktionen welche dann in der C-DLL drin wären
1: versucht 'nen kürzeren String einzutragen
2: versucht 'nen längeren String einzutragen
3: trägt einen String ein, incl. Speichermanagement
Delphi-Quellcode:
  Type PAnsiStringInfo = ^TAnsiStringInfo;
    TAnsiStringInfo = packed Record
      RefCount: LongInt;
      ElementCount: LongInt;
      DataAddr: packed Array[0..0] of AnsiChar;
    End;

  Function _SetString1(PString: PPointer): Boolean; StdCall;
    Var i: Integer;
      S: AnsiString;
      P: PAnsiStringInfo;

    Begin
      SetLength(S, 5);
      For i := 1 to 5 do S[i] := Chr($41 + Random(26));


      P := Pointer(Integer(PString^) - 8);
      If (PString^ <> nil) and (P.RefCount = 1)
          and (P.ElementCount >= Length(S)) Then Begin
        P.ElementCount := Length(S);
        MoveMemory(@P.DataAddr, PAnsiChar(S), Length(S) + 1);
        Result := True;
      End Else Result := False;
    End;

  Function _SetString2(PString: PPointer): Boolean; StdCall;
    Var i: Integer;
      S: AnsiString;
      P: PAnsiStringInfo;

    Begin
      SetLength(S, 10);
      For i := 1 to 10 do S[i] := Chr($41 + Random(26));


      P := Pointer(Integer(PString^) - 8);
      If (PString^ <> nil) and (P.RefCount = 1)
          and (P.ElementCount >= Length(S)) Then Begin
        P.ElementCount := Length(S);
        MoveMemory(@P.DataAddr, PAnsiChar(S), Length(S) + 1);
        Result := True;
      End Else Result := False;
    End;

  Type TDelphiGetMemory = function(Size: Integer): Pointer; CDecl;
       TDelphiFreeMemory = function(P: Pointer): Integer; CDecl;

  Var DelphiGetMemory: TDelphiGetMemory;
      DelphiFreeMemory: TDelphiFreeMemory;

  Procedure SetString3Memory(GetMem: TDelphiGetMemory; FreeMem: TDelphiFreeMemory); StdCall;
    Begin
      DelphiGetMemory := @GetMem;
      DelphiFreeMemory := @FreeMem;
    End;

  Function _SetString3(PString: PPointer): Boolean; StdCall;
    Var i: Integer;
      S: AnsiString;
      P: PAnsiStringInfo;

    Begin
      SetLength(S, 7);
      For i := 1 to 7 do S[i] := Chr($41 + Random(26));


      P := Pointer(Integer(PString^) - 8);
      If S > 'Then Begin
        If (PString^ = nil) or (P.RefCount = -1) Then Begin
        End Else If P.RefCount > 1 Then Begin
          Dec(P.RefCount);
        End Else If P.ElementCount <> Length(S) Then Begin
          DelphiFreeMemory(P);
        End;
        P := DelphiGetMemory(8 + Length(S) + 1);
        P.RefCount := 1;
        P.ElementCount := Length(S);
        MoveMemory(@P.DataAddr, PAnsiChar(S), Length(S) + 1);
        PString^ := Pointer(Integer(P) + 8);
      End Else Begin
        If PString^ <> nil Then
          If P.RefCount = -1 Then
            PString^ := nil
          Else If P.RefCount <> 0 Then Begin
            Dec(P.RefCount);
            If P.RefCount = 0 Then Begin
              DelphiFreeMemory(P);
              PString^ := nil;
            End;
          End;
      End;
      Result := True;
    End;
und die Testaufrufe:
Delphi-Quellcode:
  Var ZweitString: AnsiString;

  Procedure TForm1.FormCreate(Sender: TObject);
    Const BoolStr: Array[Boolean] of String = ('False', 'True ');
      ConstString = '123456789';

    Var S: AnsiString;
      B: Boolean;

    Begin
      Memo1.Lines.Add('');
      Memo1.Lines.Add('Leerstring');
      Memo1.Lines.Add('ConstString');
      Memo1.Lines.Add('String mit Referenzzähler = 1');
      Memo1.Lines.Add('String mit Referenzzähler = 2');

      Memo1.Lines.Add('');
      S := '';
      Memo1.Lines.Add(Format('x1 - False - "%s"', [S]));
      S := ConstString;
      Memo1.Lines.Add(Format('x2 - False - "%s"', [S]));
      SetLength(S, 8);
      Memo1.Lines.Add(Format('x3 - False - "%s"', [S]));
      ZweitString := S;
      Memo1.Lines.Add(Format('x4 - False - "%s"', [S]));

      Memo1.Lines.Add('');
      S := '';
      B := SetString1(S); Memo1.Lines.Add(Format('11 - %s - "%s"', [BoolStr[B], S]));
      S := ConstString;
      B := SetString1(S); Memo1.Lines.Add(Format('12 - %s - "%s"', [BoolStr[B], S]));
      SetLength(S, 8);
      B := SetString1(S); Memo1.Lines.Add(Format('13 - %s - "%s"', [BoolStr[B], S]));
      ZweitString := S;
      B := SetString1(S); Memo1.Lines.Add(Format('14 - %s - "%s"', [BoolStr[B], S]));

      Memo1.Lines.Add('');
      S := '';
      B := SetString2(S); Memo1.Lines.Add(Format('21 - %s - "%s"', [BoolStr[B], S]));
      S := ConstString;
      B := SetString2(S); Memo1.Lines.Add(Format('22 - %s - "%s"', [BoolStr[B], S]));
      SetLength(S, 8);
      B := SetString2(S); Memo1.Lines.Add(Format('23 - %s - "%s"', [BoolStr[B], S]));
      ZweitString := S;
      B := SetString2(S); Memo1.Lines.Add(Format('24 - %s - "%s"', [BoolStr[B], S]));

      Memo1.Lines.Add('');
      SetString3Memory(@GetMemory, @FreeMemory);
      S := '';
      B := SetString3(S); Memo1.Lines.Add(Format('31 - %s - "%s"', [BoolStr[B], S]));
      S := ConstString;
      B := SetString3(S); Memo1.Lines.Add(Format('32 - %s - "%s"', [BoolStr[B], S]));
      SetLength(S, 8);
      B := SetString3(S); Memo1.Lines.Add(Format('33 - %s - "%s"', [BoolStr[B], S]));
      ZweitString := S;
      B := SetString3(S); Memo1.Lines.Add(Format('34 - %s - "%s"', [BoolStr[B], S]));
    End;
Code:
Leerstring
ConstString
String mit Referenzzähler = 1
String mit Referenzzähler = 2

x1 - False - ""
x2 - False - "123456789"
x3 - False - "12345678"
x4 - False - "12345678"

11 - False - ""
12 - False - "123456789"
13 - True - "CMBVB"
14 - False - "CMBVB"

21 - False - ""
22 - False - "123456789"
23 - False - "12345678"
24 - False - "12345678"

31 - True - "CUMWNOY"
32 - True - "RIASZUT"
33 - True - "FDXUPWR"
34 - True - "HCQHWEH"
wie man sieht, geht es nur bedingt.
11 - kein String vorhanden
12 - geht nicht, da Konstante und somit ist kein Speicher reserviert
13 - Sring ist kurz genug und Referenzzählung steht auf 1
14 - Referenzzählug > 1

21 - kein String vorhanden
22 - geht nicht, da Konstante und somit ist kein Speicher reserviert
23 - Referenzzählung steht zwar auf 1, aber einzutragender String ist zu lang
24 - Referenzzählug > 1

Im Endefekt muß man den String auf seine interne Struktur zerlegen und alles selbst verwalten ... es sei denn, einer erfindet 'ne Klasse dafür

bzw. man macht auf _SetString3 eine Prozedur, welcher man zusätzlich noch 'nen C-String übergeben kann, welcher in den Delphi-String kopiert wird.

einzig und allein die 23 liese sich noch ändern, indem alles was länger ist abgeaschnitten wird.
Angehängte Dateien
Dateityp: 7z project1_110.7z (1,7 KB, 2x aufgerufen)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz