Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [IB/FB] UDFs ? (https://www.delphipraxis.net/66154-%5Bib-fb%5D-udfs.html)

Hansa 25. Mär 2006 18:54

Datenbank: FB 1.5 • Zugriff über: blubb

[IB/FB] UDFs ?
 
Hi,

habe mir mal die UDFs vorgeknöpft. Wenn hier auch was von Computername steht, hat das mit dem anderen Thread nicht viel zu tun ! Hiermit erstelle ich die DLL :

Delphi-Quellcode:
library TestUdf;

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

{$R *.res}

exports
  ComputerName;

end.
Delphi-Quellcode:
function ComputerName: PChar;
begin
  ComputerName := PChar ('TEST');
end;
Diese DLL habe ich mit IBexpert importiert. In der DB ist sie zu sehen :

SQL-Code:
DECLARE EXTERNAL FUNCTION COMPUTERNAME
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT 'COMPUTERNAME' MODULE_NAME 'TESTUDF'
Nun die Preisfrage : wie nutze ich das jetzt überhaupt ? Über UDFs ist hier so guut wie gar nichts zu finden und sonstwo hörts auch an diesem Punkt auf. 8)

mkinzler 25. Mär 2006 18:57

Re: [IB/FB] UDFs ?
 
Hallo Hansa,

Die Entrypoints sind casesensitive. Im Import mußt du es genauso schreiben, wie im Export der Dll. Verwenden kann man das wie die Builtin-Funktionen.

Hansa 25. Mär 2006 19:13

Re: [IB/FB] UDFs ?
 
Wie normale Funktion verwenden. Was ist denn dann hiermit :

SQL-Code:
  new.ANGELEGT = current_timestamp;
  new.BEZ = COMPUTERNAME;
Innerhalb BI-Trigger. ANGELEGT und BEZ sind Tabellen-Felder. current_timestamp ist wohl eine eingebaute Funktion und Computername die UDF. Letzere erzeugt die Fehlermeldung "unknown variable : COMPUTERNAME". Die UDF müßte doch "TEST" zurückliefern und dadurch BEZ auf TEST setzen. :gruebel:

mkinzler 25. Mär 2006 19:30

Re: [IB/FB] UDFs ?
 
Zitat:

Innerhalb BI-Trigger. ANGELEGT und BEZ sind Tabellen-Felder. current_timestamp ist wohl eine eingebaute Funktion und Computername die UDF.
CURRENT_TIMESTAMP ist eine Kontextvariable. MIN(), Max() usw. sind Funktionen. Aufrufe etwa so:
SQL-Code:
select COMPUTERNAME() from ...
Wobei ich nicht weiss, ob Parameterlose Funktionen erlaubt sind.

Hansa 25. Mär 2006 19:39

Re: [IB/FB] UDFs ?
 
Das interessanteste sind die drei ... :-D Und für was sollen die stehen bei der UDF ? :shock:

webcss 25. Mär 2006 19:47

Re: [IB/FB] UDFs ?
 
wie mkinzler schon sagte, UDFs sind casesensitive, das heißt:
wenn in deiner export deklaration steht
Delphi-Quellcode:
exports
   ComputerName;
solltest Du Deine UDF so einbinden:
SQL-Code:
DECLARE EXTERNAL FUNCTION COMPUTERNAME
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT 'ComputerName' MODULE_NAME 'TESTUDF'
Siehst Du den Unterschied? :wink:

mkinzler 25. Mär 2006 19:48

Re: [IB/FB] UDFs ?
 
Zitat:

Das interessanteste sind die drei ... Very Happy Und für was sollen die stehen bei der UDF ? Shocked
das Beispiel mit der parameterlosen Funktion ist vielleich schlecht gewählt. Nehemen wir mal an du hättest eine Tabellen mit einem Feld Wert. Un eine Funktion Verdopple() in der UDF. Dann würde mit der Abfrage
SQL-Code:
select wert from tabelle;
alle Werte als Ergebnis zurückgeliefert. mit
SQL-Code:
select verdopple(Wert)from Tabelle;
halt das Doppelte ( wenn in Funktion so implementiert).

Aber
SQL-Code:
new.BEZ = ComputerName();
könnte auch funktionieren, da
SQL-Code:
ja GEN_ID( ...);
auch in Triggern direkt aufgerufen werden kann.

Hansa 25. Mär 2006 20:36

Re: [IB/FB] UDFs ?
 
So, etwas rumgespielt. UDF heißt jetzt COMPUTERNAMEFUNC.

Bezieht sich das Case-sensitive auf den Delphi Teil ? Der ist jetzt vorsichtshalber so :

Delphi-Quellcode:
exports
  COMPUTERNAMEFUNC;
Trigger :

SQL-Code:
as
begin
  if (new.ID is null) then
    new.ID = gen_id(GEN_ART_ID, 1);
  if (new.angelegt is null) then
    new.ANGELEGT = current_timestamp;
  new.BEZ = COMPUTERNAMEFUNC ();
end
UDF :

SQL-Code:
DECLARE EXTERNAL FUNCTION COMPUTERNAMEFUNC
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT 'COMPUTERNAME' MODULE_NAME 'TESTUDF'
Was jetzt genau die Ursache dafür war, daß es nicht compiliert wurde ? :shock: signifikante Änderung wurde allerdigs duch das () ausgelöst. Allerdings war die UDF in IBExpert genauso grün und unterstrichen, wie das gen_id. Der Trigger braucht in diesem Fall offensichtlich das (). Denn der wird jetzt auch compiliert. Beim Commit kommt aber noch das :

Zitat:

Zitat von IBExpert
Invalid token.
invalid request BLR at offset 69.
function COMPUTERNAMEFUNC is not defined.
module name or entrypoint could not be found.

Habe mich jetzt wohl mit den Bezeichnern verhackstückelt. :cyclops: Welche Rolle spielt genau der Name der UDF und insbesondere der Entry-Point ? Was geht da genau vor sich ?

Edit : wo genau muß die DLL eigentlich hin ? Ist momentan überall. :mrgreen:

mkinzler 25. Mär 2006 20:43

Re: [IB/FB] UDFs ?
 
Zitat:

Welche Rolle spielt genau der Name der UDF und insbesondere der Entry-Point ?
Der EntryPoint bezeichnet die Funktion, welche aus der DLL geladen wird. Und exportierst eine Funktion COMPUTERNAMEFUNC versuchst aber eine mit dem Namen COMPUTERNAME zu importiere. das Funktioniert leider so nicht. :-(

[edit]
Edit : wo genau muß die DLL eigentlich hin ? Ist momentan überall. Mr. Green [/edit] Kommt darauf an was in deiner fbconf steht.

Hansa 25. Mär 2006 21:17

Re: [IB/FB] UDFs ?
 
Weiß nicht genau wieso, aber jetzt geht alles ! :thumb: Sieht so aus, daß ich immer die falsche DLL geändert, bzw. am falschen Ort hatte. Der Trigger erzeugt nun einen Feldinhalt, der von der UDF geliefert wurde. Muß das mal mit dem jetzigen Kenntnisstand von Anfang an neu machen. War vielleicht nicht schlecht, das Thema UDFs hier mal durchzukauen. IMHO sind die vorhandenen UDFs zwar mit Vorsicht zu genießen, aber wenn man weiß, wie man die selber machen kann, dann eröffnen sich schon interessante neue Perspektiven ! Allerdings bleiben noch 2 Fragen : 1. reicht die Angabe von FREE_IT aus, Speicherlecks zu vermeiden ? 2. Habe ja absichtlich deswegen kein simples integer verwendet. Allerdings vermisse ich bei Anzeige der DDL das BY REFERENCE. Obwohl in der Grid-Anzeige der UDF rechts bei "Return Mechanism" "By Reference" drin steht. 8)

webcss 25. Mär 2006 23:49

Re: [IB/FB] UDFs ?
 
Wenn Du etwas tiefer in die Materie UDF Programmierung mit Delphi einsteigen willst: UDF-Tutorial

Lemmy 26. Mär 2006 17:31

Re: [IB/FB] UDFs ?
 
Hi Hansa,

auf meiner Seite gibts dazu auch was (Serverprogrammierung von IB/FB).

Auf was Du achten musst: Wenn Du mit Strings arbeitest musst Du für Speicher sorgen! Du übergibst hier Strings an ein C/C++ Programm!
Grüße
Lemmy

Hansa 26. Mär 2006 18:50

Re: [IB/FB] UDFs ?
 
Lemmy, das ist mir schon klar. Und Deine Tutos sind längst ausgedruckt und abgeheftet. :thumb: Bzw. liegt das eine noch hier rum. :mrgreen: Eine offene Frage (siehe oben) ist noch, ob das FREE_IT alleine ausreicht den Speicher wieder freizugeben.

webcss 26. Mär 2006 19:48

Re: [IB/FB] UDFs ?
 
Alsooo, FREE_IT benutzt du in verbindung mit der speicherallozierung mit ib_util_malloc, und eigentlich nur dann notwendigerweise, wenn du strings verarbeitest und zurückgibst.
GetMem aus Delphi funktioniert anders als ib_util_malloc welches speziell eine c++ allozierung vornimmt.

Wenn du "nur" einen numerischen (z.b. integer) wert zurückgibst bzw. als parameter (fester länge) hin und zurück gibst, kannst du das result by_reference oder by_value (nicht zu empfehlen!) übergeben und abholen, da hier immer dieselbe speicheradresse verwendet wird und die größe konstant ist.

Mit Strings wie gesagt musst du den speicher mit ib_util_malloc allozieren und in deiner UDF-Dekalration mit FREE_IT wieder freigeben, sonst gibt's schrott und das ganze ist nicht mehr threadsafe!

Hansa 26. Mär 2006 20:10

Re: [IB/FB] UDFs ?
 
Mich stört halt folgendes : in IBExpert steht bei Return Mechanism "by reference" und die CheckBox für FREE_IT ist angekreuzt. In der DDL von der UDF (echtes computerchinesisch) :mrgreen: ist nur das FREE_IT zu sehen. Und Du meinst, beim Erstellen der DLL muß man das IB_UTIL_ALLOC verwenden, oder wie ? Dann muß ich mal gucken.

webcss 26. Mär 2006 22:20

Re: [IB/FB] UDFs ?
 
Zitat:

Zitat von Hansa
Mich stört halt folgendes : in IBExpert steht bei Return Mechanism "by reference" und die CheckBox für FREE_IT ist angekreuzt. In der DDL von der UDF (echtes computerchinesisch) :mrgreen: ist nur das FREE_IT zu sehen.

by reference ist der Standardmechanismus bei IB/FB.
Zitat:

Und Du meinst, beim Erstellen der DLL muß man das IB_UTIL_ALLOC verwenden, oder wie ? Dann muß ich mal gucken.
Definitiv zum allozieren von Speicher für chararrays(=strings), sonst gibts Speichersalat. :drunken:
Hier ist noch ein extensives Tutorial und schau dir mal den Quellcode von anderen UDF-Bibliotheken an.

Lemmy 27. Mär 2006 06:46

Re: [IB/FB] UDFs ?
 
Guten Morgen Hansa,

Zitat:

Zitat von Hansa
Und Du meinst, beim Erstellen der DLL muß man das IB_UTIL_ALLOC verwenden, oder wie ? Dann muß ich mal gucken.


Du solltest wirklich nochmal das Tutorial anschauen ;-) Genau das steht drin! Du brauchst die Funktion damit Du den Speicher belegen kannst - ansonsten wird das Ding Deinen PC abschißen!

Lemmy


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:02 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