Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi udf tut nicht was sie soll (https://www.delphipraxis.net/71948-udf-tut-nicht-sie-soll.html)

sancho1980 22. Jun 2006 19:05

Datenbank: firebird • Version: 1.5 • Zugriff über: ibx, ibexpert

udf tut nicht was sie soll
 
Liste der Anhänge anzeigen (Anzahl: 1)
hallo,
ich hab ein problem (wie immer *löl)
ich habe eine dll, welche 'eigentlich' tut was sie soll, nämlich in einem widestring einen substring suchen und diesen durch einen anderen substring zu ersetzen.
das projekt ist im anhang

so, dann kopiere ich die dll in mein firebird-udf-verzeichnis, starte den server neu und deklariere die udf mit:

SQL-Code:
DECLARE EXTERNAL FUNCTION REPLACESUBSTRING
    CSTRING(100),
    CSTRING(100),
    CSTRING(100)
RETURNS CSTRING(100) FREE_IT
ENTRY_POINT 'Replace' MODULE_NAME 'MyFirebirdUDFs'
Mit einem sql-aufruf wie select
SQL-Code:
replacesubstring('Muster', 'us', 'af') from rdb$database
will ich dann natürlich erreichen, dass 'Muster' zu 'Mafter' gemacht wird.
aber das ergebnis, dass mir der query zurückgibt ist immer noch 'Muster'

was mach ich falsch?

danke,

martin

mkinzler 22. Jun 2006 19:11

Re: udf tut nicht was sie soll
 
Der Aufruf der Funktion funktioniert 1.lokal 1. Beim Aufruf der Dll?

sancho1980 22. Jun 2006 19:14

Re: udf tut nicht was sie soll
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von mkinzler
Der Aufruf der Funktion funktioniert 1.lokal 1. Beim Aufruf der Dll?

versteh jetzt die frage nicht ganz, fakt is aber dass die funktion das richtige ergebnis liefert, wenn ich sie mit folgendem testprogramm laufen lasse
:

peter12 22. Jun 2006 19:17

Re: udf tut nicht was sie soll
 
Konnte es nicht in
Delphi 5 compilieren TntSysUtils fehlt mir.

Unterschiede zu meiner DLL

exports Replace name 'Replace';

Bei mir >>> exports Replace ;

function Replace(s, old, new: PWideChar): PWideChar; cdecl; export;

Bei mir >>> function Replace(s, old, new: PWideChar): PWideChar; cdecl;

Peter

sancho1980 22. Jun 2006 19:20

Re: udf tut nicht was sie soll
 
Zitat:

Zitat von peter12
Konnte es nicht in
Delphi 5 compilieren TntSysUtils fehlt mir.

Unterschiede zu meiner DLL

exports Replace name 'Replace';

Bei mir >>> exports Replace ;

function Replace(s, old, new: PWideChar): PWideChar; cdecl; export;

Bei mir >>> function Replace(s, old, new: PWideChar): PWideChar; cdecl;

Peter

ja, du brauchst dafür die tnt-unicode-controls:

http://www.tntware.com/delphicontrols/unicode/

Lemmy 22. Jun 2006 19:27

Re: udf tut nicht was sie soll
 
Hi,

Zitat aus meinen UDF-Tutorial:

Zitat:

In der nächsten Funktion sollen mit AnsiUpperCase die Zeichen in Großbuchstaben
umgewandelt werden, incl. der korrekten deutschen Umlaute. Eine Übergabe des
umgewandelten Strings als Result-Ergebnis der Funktion mit dem Typ PChar
funktioniert nicht. Hier muss jetzt etwas Aufwand betrieben werden, dass der von
der UDF verwendete Speicherbereich für den String auch den IB-Server erreicht und
von ihm korrekt freigegeben wird. Dazu dient eine Funktion in der ib_util.dll (ist im
BIN-Verzeichnis:
function ib_util_malloc(l: integer): pointer; cdecl; external
'ib_util.dll';
Diese Funktion generiert einen Zeiger auf den verwendeten Speicherbereich. Dieser
Zeiger wird anschließend an den IB-Server übergeben und der Inhalt ausgelesen.
Dann kann der Server den Speicherbereich freigeben. Die Funktion sieht dann so
aus:

Delphi-Quellcode:
function UpperChar(const p:PChar):PChar; cdecl;
{
DECLARE EXTERNAL FUNCTION UpperChar
CString(255)
RETURNS CString(255) FREE_IT
ENTRY_POINT 'UpperChar' MODULE_NAME 'MyUDF'
}
var s:string;
begin
s:=STRING(p);
s:=AnsiUpperCase(s);
Result := ib_util_malloc(Length(s)+1);
StrPCopy(Result, s);
end;
Der eingehende PChar wird in einen String umgewandelt und dieser dann durch die
Funktion AnsiUpperCase gejagt. Nun kommts: Die Stringlänge wird an die Funktion
ib_util_malloc übergeben, der den Speicherbereich alloziiert. Die Stringlänge wird
dabei um eins erhöht (weil er als Nullterminierter String zurückgegeben wird!).
Anschließend wird der String mit StrPCopy in den dafür vorbereiteten
Speicherbereich kopiert. In der Deklaration ist diesesmal für den Rückgabewert „BY
REFERENCE“ und „FREE_IT“ angegeben, damit der Server den Speicherbereich
wieder freigibt.
Das kann vielleicht auch dazu führen, dass die Funktion in Firebird nicht das macht was sie soll.

Lemmy


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz