Autor Beitrag
2cHH
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: So 27.08.06 18:53 
Hi,

mittlerweile habe ich mich mal versucht etwas mit der IDE vertraut zu machen. Weil ich sowieso schon länger vorhatte, ein einfaches Programm zu schreiben, mit dem man mehrzeilige Textersetzungen vornehmen kann, ohne sich erst mit RegEx oder einem Macrorecorder beschäftigen zu müssen, ist das dabei herausgekommen:

[url=img135.imageshack.us...35/9097/1apptr9.png]user defined image[/URL]



Funktioniert auch, geht aber bei Texten mit über 50.000 Zeichen zu sehr in die Knie. Wie kann ich das Programm (oder besser die eine Zeile ;) ) schneller machen?

ausblenden Delphi-Quelltext
1:
2:
3:
RichEditSource.Text := AnsiReplaceStr(RichEditSource.Text,
                                      RichEditSearch.Text,
                                      RichEditReplace.Text);


Das hier habe ich schon versucht, macht aber scheinbar keinen allzugrossen Unterschied:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
cont := RichEditSource.Text;
RichEditSource.Text := AnsiReplaceStr(cont,
                                      RichEditSearch.Text,
                                      RichEditReplace.Text);


Welche Möglichkeiten gibt es, um die Performance zu steigern?


Moderiert von user profile iconTino: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 28.08.2006 um 08:39
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 27.08.06 19:27 
Das ist ein Systematischer Fehler in der VCL, da Du gleich zwei Flaschenhälse in der String-Replace-Routne drin hast.

Das Beste für Deinen Fall wäre, die StringReplace-Funktion komplett selber zu schreiben, was gar nicht so schwer ist.

Ich knn leider den Quelltext der beiden Routinen in der VCL nicht als Referenz die Flaschenhälse aufzeigen, da ich den auf nem anderen Rechner hab, grob soviel zu den Fehlern: Die VCL alloziiert Speicher in Schleifen, immer wenn eine neue Ersetzung vorgenommen wurde ... Ferner werden jedes mal 3 Kopien der Strings gehandhabt, die vollständig umkopiert werden müssen, was aber vollkommener Overhead ist ...

Eine optimierte Version sieht folgendermaßen aus:

  1. Berechne den maximal anfallenden Speicher, wenn das Maximum an Ersetzungen vorgenommen werden muss vs. Stringlänge ohne Ersetzung und nehme den größeren Wert (MaxReplaceSize := Max((OrigStringLen div OrigNeedleSize) * ReplacedStringLen + OrigStringLen mod OrigNeedleSize, OrigStringLen);)
  2. Reserviere einen String entsprechender Größe (SetLength(Result, MaxReplaceSize);)
  3. Durchsuche den OriginalString zeichenweise nach dem Suchmusterr:

    1. Wenn das Suchmuster nicht mit dem aktuellen Zeichen übereinstimmt, wird das aktuelle Zeichen in den Ausgabestring kopiert.
    2. Stimmt das erste Zeichen mit dem des Sucmusters überein, merkt man sich die aktuelle Position und prüft auf Übereinstimmung
      • Bei Übereinstimmung schreibt man den Ersetzungsstring in die Ausgabe
      • Bei nichtübereinstimmung kopiert man soviele Zeichen in die Ausgabe, wie man zur Feststellung der Abweichung vom Suchmuster gebraucht hat


  4. Anpassen des Result-Strings mit SetLength um überflüssige Zeichen abzuschneiden (SetLength(Reesult, ActualSize);).


Ich denk, die Frage ist aber in ASM\Opti besser aufgehoben ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: So 27.08.06 20:14 
user profile iconBenBE hat folgendes geschrieben:
Das ist ein Systematischer Fehler in der VCL

Du meinst wohl RTL und nicht VCL. Und auch in der RTL ist es "nur" der Speichermanager, der ab Delphi 2006 durch einen neuen ersetzt wurde, der dieses Verhalten nicht mehr so extrem auslebt.

Zitat:
Die VCL alloziiert Speicher in Schleifen

Hier: "VCL" durch "AnsiStringReplace" ersetzen.


(die VCL ist nicht für alles der Schuldige :lol: )

_________________
Ist Zeit wirklich Geld?
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: So 27.08.06 20:25 
AnsiReplaceStr ist also der Schludige, thnx.


Zuletzt bearbeitet von 2cHH am So 27.08.06 20:26, insgesamt 1-mal bearbeitet
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mo 28.08.06 11:08 
Hallo,

hier : fastcode.sourceforge.net/
gibt fuer viele Funktionen eine zum erhebliche schnellere Ersetzung.
Insbesondere ansistringreplace fastcode.sourceforge...siStringReplace.html bis zu 17-fach= 1700%
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
Function       Name CPU   Presler Northwood Yonah Dothan AMD64 AMD64 X2 Total
StringReplace_JOH_IA32_4      1034  1010  1000  1000  1000  1000  6044
StringReplace_JOH_IA32_3      1000  1000  1104  1105  1049  1066  6324
StringReplace_JOH_PAS_4       1210  1202  1020  1029  1143  1140  6744
StringReplace_JOH_PAS_3       1316  1278  1105  1105  1236  1256  7296
StringReplace_EG_MMX_         1376  1462  1053  1070  1165  1187  7313
StringReplace_SHA_IA32_1      2183  2236  1662  1709  1548  1618  10956
StringReplace_EWC_IA32_2      2202  2182  1726  1733  1668  1682  11193
StringReplace_DKC_SSE2_19     2243  2386  1759  1770  1859  1903  11920
StringReplace_DKC_SSE2_20     2255  2440  1759  1775  1864  1905  11998
StringReplace_DKC_SSE_10      2366  2420  1778  1792  1885  1903  12144
StringReplace_DKC_SSE_9       2364  2400  1789  1790  1921  1957  12221
StringReplace_DKC_IA32_15     2400  2364  1851  1861  1918  1946  12340
StringReplace_DKC_IA32_16     2410  2378  1852  1865  1923  1955  12383
StringReplace_DKC_MMX_9       2417  2414  1846  1851  1927  1971  12426
StringReplace_DKC_MMX_10      2427  2494  1836  1857  1934  1976  12524
StringReplace_DKC_IA32_14     2460  2420  1869  1882  1962  1997  12590
StringReplace_DKC_MMX_11      2487  2688  1824  1827  1915  1948  12689
StringReplace_DKC_Pas_5       2511  2536  2055  2059  1900  1924  12985
StringReplace_DKC_Pas_4       3660  4112  2989  3011  2523  2784  19079
StringReplace_HV_IA32_1       8224  8096  5904  6128  5533  5734  39619
StringReplace_REF_PAS_1       8188  8598  5892  6044  6076  6580  41378
StringReplace_RTL_PAS_1      17376  16298  15058  15722  11217  11501  87172


Gruss Horst
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 13:44 
user profile iconHorst_H hat folgendes geschrieben:
hier : fastcode.sourceforge.net/
gibt fuer viele Funktionen eine zum erhebliche schnellere Ersetzung.


Hi,

thnx, aber ich hatte gestern abend schon selber eine Funktion geschrieben. Zuerst so wie von BenBE vorgeschlagen, dann habe ich noch versucht, die Funktion zu optimieren, so dass nicht immer ein Zeichen nach dem anderen in den Puffer kopiert wird, sondern stattdessen eine Variable hochgezählt, anhand der dann alle (bisherigen) Zeichen auf einmal kopiert werden können:


ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
char* strReplace(char* sCont, char* sSearch, char* sRepl)
    {
    int nCont = strlen(sCont);
    int nSearch = strlen(sSearch);
    int nRepl = strlen(sRepl);
    ;
    int nBuff = (nCont / nSearch) * nRepl 
              + (nCont % nSearch);
    nBuff = (nBuff < nCont) ? nCont : nBuff;
    char* sBuff = malloc(sizeof(char) * nBuff);
    *sBuff = '\0';
    ;
    int nToCopy = 0;
    while(*sCont)
        {
        if(*sCont == *sSearch)
            {
            char* pCont = sCont;
            char* pSearch = sSearch;
            while((*++pCont == *++pSearch) &&
                  (*pCont) && (*pSearch));
            ;
            if(!*pSearch)
                {
                strncat(sBuff, (sCont - nToCopy), nToCopy);
                nToCopy = 0;
                strcat(sBuff, sRepl);
                sCont += nSearch;
                continue;
                }
            }
        sCont++;
        nToCopy++;
        }
    strncat(sBuff, (sCont - nToCopy), nToCopy);
    return sBuff;
    }


Soweit ich es getestet habe, scheint die Funktion ok zu sein.


Die Frage ist jetzt, ob ich bei DevCpp einfach ein DLL-Projekt anlegen kann, die Funktion compilieren und dann die Funktion in Delphi einbinden kann?

Gruss aus Hamburg

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Mo 28.08.06 14:04 
Zitat:

Die Frage ist jetzt, ob ich bei DevCpp einfach ein DLL-Projekt anlegen kann, die Funktion compilieren und dann die Funktion in Delphi einbinden kann?
Sollte gehen.

_________________
Markus Kinzler.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 28.08.06 14:14 
@user profile icon2cHH: Da Du mit PChars arbeitest, solltest Du ein zusätzliches Byte am Ende für den Nullterminator mitreservieren. Inwiefern strncat dies automatisch macht, weiß ich aber ATM nicht. Bei malloc muss er mit enthalten sein (Macht SetLength intern, weshalb ich das nicht mit aufgeführt hab).

Weiterhin scheint es mir so, als ob du Potetielle Buffer Overruns in deiner Routine hast, wenn das Suchmuster am Ende des Strings gefunden wird.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 14:36 
user profile iconBenBE hat folgendes geschrieben:
@user profile icon2cHH: Da Du mit PChars arbeitest,


Sorry, da kann ich nicht ganz folgen.

Wieso PChar, in C gibt es imho nur eine Sorte Chars, von Unicode mal abgesehen?



user profile iconBenBE hat folgendes geschrieben:
@user profile icon2cHHein zusätzliches Byte am Ende für den Nullterminator mitreservieren....
Weiterhin scheint es mir so, als ob du Potetielle Buffer Overruns in deiner Routine hast, wenn das Suchmuster am Ende des Strings gefunden wird.


strcat passt schon, das geht ja alles in den Buffer, der ist gross genug, Leerchars oder fehlende Chars gibt es da auch nicht.

Potentielle Buffer Overruns - Wie soll das genau passieren? das würde ich gerne verhindern.




Hehe, vorhin habe ich mich nicht genau ausgedrückt, ich exporiere die DLL, soweit ok,
aber was mache ich in Delpi, gibt es da ein DLL-Import Tutorial?

Oder ist Delphi so performant, dass es zu überlegen wäre, den Code auf Delphi zu portieren?


Gruss aus Hamburg
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Mo 28.08.06 14:42 
Zitat:
Wieso PChar, in C gibt es imho nur eine Sorte Chars, von Unicode mal abgesehen?
Dieser Typ heißt in Delphi PChar ( Pointer to Char)

_________________
Markus Kinzler.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 28.08.06 14:51 
user profile icon2cHH hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
@user profile icon2cHH: Da Du mit PChars arbeitest,


Sorry, da kann ich nicht ganz folgen.

Wieso PChar, in C gibt es imho nur eine Sorte Chars, von Unicode mal abgesehen?

Jup, ABER ^^ Char* ist wird in Delphi als Zeiger auf ein Zeichen (Pointer to Char --> PChar) übersetzt. Und diese umfassen neben den Daten am Ende ein zusätzliches Byte zur Nullterminierung, welches Du zusätzlich mit reservieren musst.

user profile icon2cHH hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
ein zusätzliches Byte am Ende für den Nullterminator mitreservieren....
Weiterhin scheint es mir so, als ob du Potetielle Buffer Overruns in deiner Routine hast, wenn das Suchmuster am Ende des Strings gefunden wird.


strcat passt schon, das geht ja alles in den Buffer, der ist gross genug, Leerchars oder fehlende Chars gibt es da auch nicht.

Potentielle Buffer Overruns - Wie soll das genau passieren? das würde ich gerne verhindern.


Leerchars und Fehlende Chars mein ich auch nicht. Ich hab beim Überfliegen des Sources einen Teil deiner Abbruchbedingung übersehen, der EndOfString korrekt prüft. Würde dieser Teil fehlen, könnte es passieren, dass bei einem Match am Ende des String Daten hinter den zu vergleichenden Strings analysiert werden würden. Die Prüfung ist aber gegeben (bei näherem Hinsehen).

user profile icon2cHH hat folgendes geschrieben:
Hehe, vorhin habe ich mich nicht genau ausgedrückt, ich exporiere die DLL, soweit ok,
aber was mache ich in Delpi, gibt es da ein DLL-Import Tutorial?

Oder ist Delphi so performant, dass es zu überlegen wäre, den Code auf Delphi zu portieren?

Gruss aus Hamburg

Wenn man mit Delphi korrekt programmiert, kann es auch sehr performant sein ... Im Normalfall geht es aber mit C++ einen Tick schneller ...

Zum Import:
ausblenden Delphi-Quelltext
1:
Function DeinReplaceStr(sCont: PChar; sSearch: PChar; sReplace: PChar): PChar; external 'Deine.dll' name 'strReplace';					

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 14:57 
user profile iconBenBE hat folgendes geschrieben:
diese umfassen neben den Daten am Ende ein zusätzliches Byte zur Nullterminierung, welches Du zusätzlich mit reservieren musst.


Übergeben wird ja ein Nullterminierter String (sBuff). Wenn ich es richtig verstanden habe,
hätte man die Problematik, wenn man einzelne Chars übergeben würde, nicht?


user profile iconBenBE hat folgendes geschrieben:
Zum Import:
ausblenden Delphi-Quelltext
1:
Function DeinReplaceStr(sCont: PChar; sSearch: PChar; sReplace: PChar): PChar; external 'Deine.dll' name 'strReplace';					



Thnx, dann werde ich mal mein Glück versuchen.... ;)

Gruss aus Hamburg
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 16:44 
Hi,

die DLL habe ich jetzt fertig:

[url=img241.imageshack.us...1/replacedllig1.png]user defined image[/URL]


[url=img102.imageshack.us...placedlltestta1.png]user defined image[/URL]


Wie man sieht, lässt sich die DLL auch in das Projekt einbinden.
Leider bekomme ich unter Delphi keine korrekten Ergebnisse.

Man könnte denken, dass es an der DLL liegt, aber die ist wohl OK,
denn in C funktioniert das ganze, mit Ergebnis.


Bei Delphi muss es wohl Probleme it der Übergabe des Strings o.ä. geben,
mir wird bei jeder Eingabe immer nur:

ausblenden Quelltext
1:
hù					


zurückgegeben. Hier mein DLL-Aufruf:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
implementation

{$R *.dfm}

Function MyReplace(sSource: PChar; sSearch: PChar; sReplace: PChar): PChar; external 'replaceDLL.dll' name 'strReplace';

procedure TForm1.ButtonReplaceClick(Sender: TObject);
begin
pSource := PChar(RichEditSource.Text);
pSearch := PChar(RichEditSearch.Text);
pReplace := PChar(RichEditReplace.Text);
pResult := MyReplace(pSource,
                     pSearch,
                     pReplace);
RichEditSource.Text := AnsiString(pResult);
end;



Jibbet da irschendwälsche Driggs?
(Gibt es da irgendwelche Tricks)

Gruss aus Hamburg
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Mo 28.08.06 16:53 
Delphi verwendet eine andere Übergabekonvention. Verwende mal StdCall;

_________________
Markus Kinzler.
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 17:11 
user profile iconmkinzler hat folgendes geschrieben:
Delphi verwendet eine andere Übergabekonvention. Verwende mal StdCall;



Cool, jetzt funktioniert es, thnx.

*freu*



Gruss aus Hamburg
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Mo 28.08.06 17:14 
Im nächsten Schritt kannst du ja zu Übung die Funktion in Delphi implemnetieren ;-)

_________________
Markus Kinzler.
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 17:54 
user profile iconmkinzler hat folgendes geschrieben:
Im nächsten Schritt kannst du ja zu Übung die Funktion in Delphi implemnetieren



Das wäre bestimmt eine gute Übung, ich glaube, dass mache ich auch.




Aber mit der DLL habe ich mich doch etwas zu früh gefreut:

Auf der Konsole funktioniert die DLL auch mit grösseren Strings mehrmals hintereinander:

[url=img100.imageshack.us...cedllconsolefu1.png]user defined image[/URL]

Bei dem GUI-Programm gibt es einen fehlerhaften Zugriffsversuch auf 0x00000000.
Die erste Ersetzung ist verflixt schnell, so wie ich mir das auch vorgestellt habe,
leider kann man danach keine zweite mehr machen und müsste das Programm neustarten.


Ich glaube, es könnte immer noch an dem DLL-Aufruf liegen, nur wo genau?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mo 28.08.06 20:04 
user profile icon2cHH hat folgendes geschrieben:
user profile iconmkinzler hat folgendes geschrieben:
Delphi verwendet eine andere Übergabekonvention. Verwende mal StdCall;

Cool, jetzt funktioniert es, thnx.

Hast du auch die C-Funktion als __stdcall markiert?

Zudem hast du da ein Speicherleck, denn der von dir zurückgegebene char* wird nicht mehr freigegeben. (und versuche erst gar nicht den mit FreeMem freizugeben; er wurde mit malloc() reserviert, muss also auch mit free() freigegeben werden)

_________________
Ist Zeit wirklich Geld?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 28.08.06 20:34 
Tipp: Schreib deine Funktion so um, dass der Ausgabepuffer und dessen Speichergröße von der Anwendung reserviert werden muss:

ausblenden Delphi-Quelltext
1:
Function MyReplace(sSource: PChar; sSearch: PChar; sReplace: PChar; sResult: PChar; var nResult: Integer): Boolean; stdcallexternal 'replaceDLL.dll' name 'strReplace';					


ausblenden C#-Quelltext
1:
__stdcall bool strReplace(char* sCont, char* sSearch, char* sRepl, char* sResult, int32* nResult)					


Wobei Result entweder True für "Ersetzung erfolgreich ausgeführt" und False "Nicht genug Speicher oder anderer Fehler!" bedeutet. Zu den Parametern sResult und nResult: sResult ist dein vorreservierter Puffer und nResult dessen größe. Ist die Größe nResult < dem Maximal benötigten Speicher, so wird nResult der Maximal zu erwartende Speichergröße zugewiesen und sResult unbeachtet gelassen. ist sResult nil, gilt das gleiche. Nach der Ersetzung wird sResult an der richtigen Stelle mit einem #0-Nullterminator abgeschlossen und nResult die Größe des Strings zugewiesen. In deinem Programm hast Du dann immer zwei Aufrufe, bei denen der erste kaum Rechenzeit benötigt (da nur eine kleine Berechnung durchgeführt wird) und der zweite Aufruf die eigentliche Ersetzung ausführt. Dann muss sich immer die Anwendung um die Speicherreservierung kümmern und du bekommst damit keine Probleme mehr in der DLL.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
2cHH Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 28.08.06 20:46 
Es funktioniert jetzt 1A, es war ein kleiner Fehler in der DLL, der grosse Auswirkungen hatte.
Das Proggi ist jetzt auch deutlich schneller, als mit AnsiReplaceStr.

*wieder freu*


Ja, stimmt, der Speicher wird solange reserviert, wie das Programm läuft.

In diesem Fall macht das aber nichts, weil das Programm nicht ständig laufen soll.
Es handelt sich um ein paar KB, die dann wieder freigegeben werden,
wenn das Programm beendet wird.



Trotzdem wäre es ganz interessant, das mal auszuprobieren.
Du meinst, Delphi hat auch eine Möglichkeit, um Speicher zu allozieren
und freizugeben, die mit der von C kombatibel ist?

Das wäre ja nicht schlecht. Werde ich nachher mal versuchen.



Die DLL brauche ich ja wohl nicht wie in C mit "Bool FreeLibrary(ModuleHandle)"
wieder freizugeben, ich denke das wird Delphi schon machen, oder?



So langsam fängt Delphi an, Spass zu machen ;)



---------------



ps:

user profile iconBenBE hat folgendes geschrieben:
Tipp: Schreib deine Funktion so um, dass der Ausgabepuffer und dessen Speichergröße von der Anwendung reserviert werden muss:


Sorry, das haben wir parallel gepostet.
Deine Quelltexte werde ich mir auf jeden Fall kopieren,
da kann ich bestimmt auch noch was von lernen.



ps2: Du hattest ganz zu Anfang übrigens Recht, da hat ein Byte gefehlt.
Die Funktion strlen rechnet in C nicht das '\0' mit.
Dann war noch ein Division durch 0 möglich, die ich jetzt vorher abfange.




Gruss aus Hamburg