AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird UDF Funktion für Delphi mit CAHR(5) Parameter
Thema durchsuchen
Ansicht
Themen-Optionen

Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

Ein Thema von mischerr · begonnen am 26. Jan 2021 · letzter Beitrag vom 27. Jan 2021
Antwort Antwort
Benutzerbild von mischerr
mischerr

Registriert seit: 6. Feb 2004
Ort: Konz
238 Beiträge
 
Delphi 12 Athens
 
#1

Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 26. Jan 2021, 15:54
Datenbank: Firebird x64 • Version: 2.5 • Zugriff über: IBDAC
Hallo!

Ich bräuchte mal eure Hilfe:

Ich habe eine Tabelle mit je einer Spalte "GEWICHT" DOUBLE PRECISION und "EINHEIT" CHAR(5) (z.B. 1.0, 'kg' oder 2.0, 'lbs').
Nun brauche ich eine UDF Funktion welche mit das Gewicht abhängig von der Einheit umrechnet: GetGewichtAs.

Meine myUDF64.DLL:
Code:
function GetGewichtAs(var Gewicht: double; const VonEinheit, NachEinheit: PAnsiChar): double;
function GetGewichtAs2(var Gewicht: double; VonEinheit, NachEinheit: integer): double;

exports GetGewichtAs, GetGewichtAs2;
Meine UDF in der DB:
Code:
DECLARE EXTERNAL FUNCTION GETGEWICHTAS DOUBLE PRECISION, CSTRING(255), CSTRING(255) RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'GetGewichtAs' MODULE_NAME 'myUDF64';
DECLARE EXTERNAL FUNCTION GETGEWICHTAS2 DOUBLE PRECISION, INTEGER, INTEGER RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'GetGewichtAs2' MODULE_NAME 'myUDF64';
Die Funktion GETGEWICHTAS2(1.0, 0, 1) funktioniert, aber GETGEWICHTAS(1.0, 'kg, 'lbs') liefert immer folgende Fehler:

Code:
Implementation of text subtype 255 not located.
SQL Code: -204
IB Error Number: 335544568

Da mir die Ideen ausgehen bin ich für jeden Tipp dankbar!.
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 26. Jan 2021, 16:01
würde sicherlich helfen den implementierten code zu sehen,
ein pchar reserviert benötigten speicher nicht automatisch und
als speichermanager brauchst du den aus der ib_util.dll, weil
der in delphi verfügbare nicht so threadfest ist wie firebird
das braucht.
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 26. Jan 2021, 16:02
und unabhängig davon, warum nicht fb3 und dort als stored function umsetzen, ist alles viel einfacher
und immer multiplattform und stabiler als udfs (die es irgendwann auch so nicht mehr geben wird in
neueren firebird versionen)
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 27. Jan 2021, 06:05
Hallo
fehlt da nicht stdcall?
Und warum ist Gewicht ein var-Parameter?

Ich würde die Funktion erst mal nur 0.0 zurückgeben lassen,
um Probleme bei der Implementierung auszuschließen.
Heiko

Geändert von hoika (27. Jan 2021 um 06:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von mischerr
mischerr

Registriert seit: 6. Feb 2004
Ort: Konz
238 Beiträge
 
Delphi 12 Athens
 
#5

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 27. Jan 2021, 07:18
Guten Morgen und zuerst einmal vielen Dank für die Rückmeldungen!

@hoika:
stdcall?
Die Deklaration der Funktionen erfolgt mit "cdecl" analog zu vielen Beispielen im Netz. Sorry, hatte ich vergessen mit zu kopieren.

Deklaration von "Gewicht" als var:
Ich ging davon aus dass das so korrekt ist da die Übergabe "by reference" erfolgt.

0 Zurückgeben:
Die Rückgabe funktioniert nur bei dieser Funktion nicht, bei allen anderen jedoch einwandfrei.
Auch wenn ich in der Funktion direkt 0 zurückgebe und und diese direkt beende funktioniert es nicht.

@IBExpert:
Warum (noch) nicht FB3?
Weil das ein recht großes Projekt mit knapp 300 Tabellen ist und ich im Moment keine Zeit habe es auf Kompatibilität zu testen.
Außerdem bedient der Server noch ein paar andere Anwendungen / Datenbanken.

Warum nicht als stored function?
Es gibt diese Funktion funktionsfähig bereits als stored function.
Da ich diese jedoch innerhalb von Aggregatfunktionen (i.d.R. SUM) einsetzen muss, erhoffe ich mir von der UDF Variante eine bessere Performance.

Speichermanager ib_util.dll?
Wie verwendet man den denn? Ich verwende aktuell Delphi 10.3 mit Zielplattform Win64.

Hier mal mein aktueller Code:

Gruß,
Micha

Code:
library myUDF64;

uses SysUtils, Classes, UDF.Functions in 'UDF.Functions.pas';

{$R *.res}

exports GetGewichtAs, GetGewichtAs2;

begin
end.
Code:
unit UDF.Functions;

interface

uses SysUtils, Classes;

const M_KG = 0; // Standard
      M_LBS = 1;

function GetGewichtAs(var Gewicht: double; const VonEinheit, NachEinheit: PAnsiChar): double; cdecl;
function GetGewichtAs2(var Gewicht: double; var VonEinheit, NachEinheit: integer): double; cdecl;

implementation

function GetGewichtAs(var Gewicht: double; const VonEinheit, NachEinheit: PAnsiChar): double;
var kg: double;
    v, n: string;
begin
  if (Gewicht=0) or
     (VonEinheit=nil) or
     (NachEinheit=nil) then
    result:= Gewicht
  else begin
    v:= String(VonEinheit);
    n:= String(NachEinheit);
    if SameText(v, n) then
      result:= Gewicht
    else begin
      if SameText(v, 'LBS') then
        kg:= Gewicht/2.20462
      else
        kg:= Gewicht;
      if SameText(n, 'LBS') then
        result:= kg*2.20462
      else
        result:= kg;
    end;
  end;
end;

function GetGewichtAs2(var Gewicht: double; var VonEinheit, NachEinheit: integer): double;
var kg: double;
begin
  if Gewicht=0 then
    result:= Gewicht
  else begin
    if VonEinheit=NachEinheit then
      result:= Gewicht
    else begin
      if VonEinheit<>M_KG then
        kg:= Gewicht/2.20462
      else
        kg:= Gewicht;
      if NachEinheit<>M_KG then
        result:= kg*2.20462
      else
        result:= kg;
    end;
  end;
end;

end.

Nachtrag:
Generell kann ich sagen dass die FB Installation nicht das Problem ist, denn wenn ich folgende UDF einrichte, bekomme ich ein Ergebnis.
Daher denke ich, dass das Problem bei meiner DLL zu suchen ich.

Code:
DECLARE EXTERNAL FUNCTION STRLEN
CSTRING(80)
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';

Geändert von mischerr (27. Jan 2021 um 08:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von mischerr
mischerr

Registriert seit: 6. Feb 2004
Ort: Konz
238 Beiträge
 
Delphi 12 Athens
 
#6

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 27. Jan 2021, 09:28
Hat sich erledigt - es funktioniert!
Der o.g. Code ist korrekt.

Es scheint an meiner "EMS SQL-Manager"-Version gelegen zu haben, welcher scheinbar den CharSet (UNICODE_FSS) beim Einrichten der UDF nicht richtig setzt.

Wenn ich die UDF per FlameRobin einrichte funktioniert es.

Code:
DECLARE EXTERNAL FUNCTION GETGEWICHTAS DOUBLE PRECISION, CSTRING(5), CSTRING(5) RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'GetGewichtAs' MODULE_NAME 'myUDF64';
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Firebird UDF Funktion für Delphi mit CAHR(5) Parameter

  Alt 27. Jan 2021, 09:39
aus meiner sicht ohne weiter meinen eigenen uralt code rauszuholen ist das hier immer noch korrekt

https://www.delphipraxis.net/485813-post.html

wenn du nach ib_util_malloc suchst solltest du da passende beispiele finden

ist insbesondere weiterhin wichtig wenn du result als pchar hast, wenn das aber nun auch
so funktioniert, um so besser
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:37 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