Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi udf in firebird deklarieren (https://www.delphipraxis.net/71567-udf-firebird-deklarieren.html)

sancho1980 17. Jun 2006 11:40

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

udf in firebird deklarieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
hallo

ich hab mal versucht, mit hilfe von diesem dokument (udfs in delphi bauen) mir eine eigene udf in delphi zu schreiben und sie in firebird zu deklarieren, aber das klappt nicht ganz...könnt ihr mir sagen was ich falsch mache (delphi-projekt im anhang):

habe also dll wie im anhang zu sehen gebaut und wollte das ganze dann in meiner datenbank deklarieren:

SQL-Code:
declare external function "replace(string varchar(100), old varchar(100), new varchar(100))"
returns varchar(100)
entry_point "Replace"
module_name "MyFirebirdUDFs";
aber das klappt nicht ganz... :cyclops:

danke,

martin

ps: die dll hab ich natürlich in mein firebird-bin-verzeichnis kopiert!

peter12 17. Jun 2006 11:45

Re: udf in firebird deklarieren
 
Ich mach udf mit hilfe von ipexpert



DECLARE EXTERNAL FUNCTION
( Name des udf in Firebird ) "NAME"
FLOAT
RETURNS FLOAT BY VALUE
ENTRY_POINT 'zahl'
MODULE_NAME
(name des udf im Delphi code) 'udfrand'

So verständlich

peter

sancho1980 17. Jun 2006 13:15

Re: udf in firebird deklarieren
 
Zitat:

Zitat von peter12
Ich mach udf mit hilfe von ipexpert



DECLARE EXTERNAL FUNCTION
( Name des udf in Firebird ) "NAME"
FLOAT
RETURNS FLOAT BY VALUE
ENTRY_POINT 'zahl'
MODULE_NAME
(name des udf im Delphi code) 'udfrand'

So verständlich

peter

Ne, leider nicht.
Kannst du mir das mal anhand meiner UDF zeigen, bitte?

Danke,

Martin

marabu 17. Jun 2006 14:09

Re: udf in firebird deklarieren
 
Hallo Martin.

Ohne Anspruch auf Schönheit - habe nur die nötigen Verbiegungen an deinem Code durchgeführt:

Delphi-Quellcode:
unit Strings;

interface

uses
  SysUtils;

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

implementation

function Replace(s, old, new: PChar): PChar;
begin
  Result := PChar(StringReplace(String(S), String(Old), String(New), [rfReplaceAll]));
end;

end.
Und natürlich muss die UDF noch der Datenbank bekannt gemacht werden:

SQL-Code:
DECLARE EXTERNAL FUNCTION REPLACE /* ANSIUPPER */
    CSTRING(100), CSTRING(100), CSTRING(100)
RETURNS CSTRING(100) FREE_IT
ENTRY_POINT 'Replace' MODULE_NAME 'MyFirebirdUDFs'
Anstelle in das BIN-Verzeichnis solltest du die library in das UDF-Verzeichnis von FireBird schieben.

Getippt und nicht getestet.

Grüße vom marabu

Edit: Es muss REPLACE heißen, nicht ANSIUPPER

peter12 17. Jun 2006 16:38

Re: udf in firebird deklarieren
 
martin hat geschrieben

ps: die dll hab ich natürlich in mein firebird-bin-verzeichnis kopiert!

Die DLL datei muß im Unterverzeichnis /UDF liegen.

peter

sancho1980 17. Jun 2006 22:06

Re: udf in firebird deklarieren
 
Zitat:

Zitat von marabu
Hallo Martin.

Ohne Anspruch auf Schönheit - habe nur die nötigen Verbiegungen an deinem Code durchgeführt:

Delphi-Quellcode:
unit Strings;

interface

uses
  SysUtils;

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

implementation

function Replace(s, old, new: PChar): PChar;
begin
  Result := PChar(StringReplace(String(S), String(Old), String(New), [rfReplaceAll]));
end;

end.
Und natürlich muss die UDF noch der Datenbank bekannt gemacht werden:

SQL-Code:
DECLARE EXTERNAL FUNCTION ANSIUPPER
    CSTRING(100), CSTRING(100), CSTRING(100)
RETURNS CSTRING(100) FREE_IT
ENTRY_POINT 'Replace' MODULE_NAME 'MyFirebirdUDFs'
Anstelle in das BIN-Verzeichnis solltest du die library in das UDF-Verzeichnis von FireBird schieben.

Getippt und nicht getestet.

Grüße vom marabu

Hi Marabu,
ein paar Fragen:

1) Warum PChar und nicht WideString?
2) Was hat es mit cstring auf sich? Kann ich der Funktion dann varchar-Parameter übergeben?
3 Wieso ANSIUPPER? Die Funktion sollte ja eigentlich in Firebird auch Replace heißen...
4) Wofür steht FREE_IT?

Danke schonmal für die Antwort!
Martin

marabu 17. Jun 2006 22:53

Re: udf in firebird deklarieren
 
Hi, zu deinen Fragen:

(1) PChar, weil ich regelmäßig ISO8859-1 speichere. Könnte bei dir auch PWideChar sein, aber das habe ich noch nicht ausprobiert.
(2) CSTRING, weil ich keine andere Möglichkeit kenne. Auch ich habe irgendwann mal den Artikel von Greg Deatz gelesen und mit den enthaltenen Informationen eine UDF zu bauen versucht.
(3) ANSIUPPER ist ein Überbleibsel von dem Code, den ich mal für einen anderen thread geschrieben hatte und hier nicht sorgfältig genug angepasst habe. Sorry.
(4) FREEIT ist das Schlüsselwort, welches anzeigt, dass du keine Ambitionen hast den von Interbase mit dessen memory management functions angeforderten Speicher mit Delphi frei zu geben.

Und vergiss nicht, was auch Peter dir nochmal geschrieben hat: \UDF und nicht \BIN ist das richtige Standard-Verzeichnis.

Gute Nacht

marabu

sancho1980 17. Jun 2006 23:31

Re: udf in firebird deklarieren
 
Danke, das mit dem Deklarieren klappt jetzt.
Nur will ich jetzt

ausführen, bekomm ich:

Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements.
Access to UDF library "MyFirebirdUDFs.DLL" is denied by server administrator.

Dabei bin ich als sysdba eingeloggt!

mkinzler 18. Jun 2006 09:41

Re: udf in firebird deklarieren
 
-Was für ein Betriebssystem?
-Ist der Zugriff auf das Verzeichnis in der Konfig freigegeben?
-Zugriffsrechte auf Datei

sancho1980 18. Jun 2006 10:40

Re: udf in firebird deklarieren
 
Zitat:

Zitat von mkinzler
-Was für ein Betriebssystem?

stinknormales WinXp

Zitat:

Zitat von mkinzler
-Ist der Zugriff auf das Verzeichnis in der Konfig freigegeben?

In firebird.conf steht:

UdfAccess = Restricted

Die dll befindet sich in C:\Programme\Firebird\Firebird_1_5\UDF. Soweit ich weiß, wird das Verzeichnis automatisch miteinbezogen. Hatte es auch schon mal explizit dahinter geschrieben. Da kam die gleiche Meldung. Wenn ich es abändere auf

UdfAccess = Full

dann bekomm ich statt dem vorherigen Fehler diesen:

Invalid token.
invalid request BLR at offset 63.
function REPLACE is not defined.
module name or entrypoint could not be found.

Zitat:

Zitat von mkinzler
-Zugriffsrechte auf Datei

Gibt's sowas in Windows?

mkinzler 18. Jun 2006 10:44

Re: udf in firebird deklarieren
 
Hast du die UDF per SQL-Skript in die DB eingebunden?

sancho1980 18. Jun 2006 10:51

Re: udf in firebird deklarieren
 
ja, die ist deklariert...mit der deklaration gibt's keine probleme; sie wird auch in ixexpert aufgelistet...

mkinzler 18. Jun 2006 10:59

Re: udf in firebird deklarieren
 
Bei Import/Export von Dll-Funktionen wird Groß-/Kleinschreibung unterschieden.
Ist die Bezeichnung bei beiden gleich?

sancho1980 18. Jun 2006 11:48

Re: udf in firebird deklarieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von mkinzler
Bei Import/Export von Dll-Funktionen wird Groß-/Kleinschreibung unterschieden.
Ist die Bezeichnung bei beiden gleich?

Ja, schau's dir bitte mal an!

Danke,

Martin

mkinzler 18. Jun 2006 11:57

Re: udf in firebird deklarieren
 
Deine Dll exportiert ja garnichts. Du mußt die Funktion auch exportieren.

sancho1980 18. Jun 2006 15:27

Re: udf in firebird deklarieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
tatsächlich
das muss mir durch die lappen gegangen sein, als ich die änderungen vom marabu übernommen hab.
aber es geht trotzdem nicht :wall:
ich konstatiere nochmal:
-die dll ist jetzt so, wie ich sie jetzt noch einmal hochgeladen hab
-meine firebird.conf hab ich auch mal hochgeladen
-MyFirebirdUDFs.dll hab ich nach C:\Programme\Firebird\Firebird_1_5\UDF kopiert
-danach hab ich den fb-server gestoppt und gestartet
-danach hab ich in ibexpert meine udf folgendermaßen deklariert:

SQL-Code:
DECLARE EXTERNAL FUNCTION REPLACE
    CSTRING(100), CSTRING(100), CSTRING(100)
RETURNS CSTRING(100) FREE_IT
ENTRY_POINT 'Replace' MODULE_NAME 'MyFirebirdUDFs'
Das schien erstmal zu klappen:

------ Performance info ------
Prepare time = 0ms
Execute time = 0ms
Current memory = 955.924
Max memory = 1.035.488
Memory buffers = 2.048
Reads from disk to cache = 0
Writes from cache to disk = 3
Fetches from cache = 39

-dann versucht, folgendes auszuführen:
SQL-Code:
select replace('hallo', 'al', 'la') from rdb$database;
Fehler:

Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements.
Access to UDF library "MyFirebirdUDFs.DLL" is denied by server administrator.

Hat irgendjemand es geschafft, meine UDF zum Laufen zu kriegen? Wo liegt mein verdammter Fehler? Überall im Netz steht, es sei so 'unwahrscheinlich einfach' UDF's zu schreiben - wenn das nochmal einer sagt, dann :spin2:

mkinzler 18. Jun 2006 15:35

Re: udf in firebird deklarieren
 
Besser so

Delphi-Quellcode:
library MyFirebirdUDFs;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }
 

uses
  SysUtils,
  Classes,
  Strings in 'Strings.pas';

{$R *.res}
exports Replace name 'Replace';
begin
end.
Was steht in der Konfig?
Dies
Code:
UdfAccess = Restrict UDF
?

sancho1980 18. Jun 2006 15:52

Re: udf in firebird deklarieren
 
oh
Zitat:

Zitat von mkinzler

Was steht in der Konfig?
Dies
Code:
UdfAccess = Restrict UDF
?

Ohmannomann, da stand

Code:
UdfAccess = Restrict
Woher sollt ich wissen, dass da noch UDF dahinter muss?

Dank dir,

martin


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 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 by Thomas Breitkreuz