Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Fehler bei ADOConnection.Create als DLL (https://www.delphipraxis.net/199625-fehler-bei-adoconnection-create-als-dll.html)

martin001 6. Feb 2019 18:25

Datenbank: sybase sql-anywhere • Version: 17.45 • Zugriff über: ODBC

Fehler bei ADOConnection.Create als DLL
 
Entwicklungsumgebung: RAD Studio 10.1 Berlin für 64 Bit + Eclipse (Java)

Hallo Zusammen,
ich stelle über eine DLL einen Datenbankzugriff einem Java-Programm zur Verfügung.
Bei dem Aufruf TADOConnection.create entsteht in der Java-Umgebung folgende Fehlermeldung:


Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:390)
at com.sun.jna.Function.invoke(Function.java:323)
at com.sun.jna.Library$Handler.invoke(Library.java:23 6)
at com.sun.proxy.$Proxy0.GetNewEntries(Unknown Source)
at Movement.Verwaltung.getCollectionTasks(Verwaltung. java:708)
at Movement.Verwaltung.addScrollListViewtoRigthPanel( Verwaltung.java:292)
at Movement.Verwaltung.<init>(Verwaltung.java:111)
at Main.main(Main.java:6)

Wobei GetNewEntries eine der Proceduren ist, die durch die Delpph-DLL dem Java-Programm zur Verfügung gestellt wird, und die unten dargestellte Procedure AbfrageAusAPLTest aufruft.

1.) In der Testphase wurde kein Datenbankzugriff ausgeführt sondern nur fest hinterlegte Daten per DLL ausgetauscht. Das war fehlerfrei.
2.) Wenn ich die Procedure AbfrageAusAPLTest nicht über eine DLL exportiere, sondern von einem Delphiformular aufrufe, tritt auch mit der Datenbank kein Fehler auf.
3.) Wenn die Zeile "//showmessage('1. in AbfrageAusAPL: '+wherestring);[/I]" nach dem Begin der Procedure entkommentiert wird, tritt auch mit der DLL kein Fehler auf.
4.) Wenn ich die Zeile showmessage durch sleep ersetze, tritt der Fehler mit der DLL wieder auf.

Hat irgend jemand eine Idee wo das Problem liegt?
Eine unsaubere Lösung wäre auch das showmessage-Fenster kurz zu öffnen und nach 200 MS automatisch zu schließen. Weiß jemand wie das gehen könnte?



Delphi-Quellcode:
unit APLData2test;

interface

uses
  System.SysUtils, System.Classes,Data.Win.ADODB, dialogs,dek_sam;

type
  TDataModule2test = class(TDataModule)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
Procedure AbfrageAusAPLTest(WhereString:string; var AusAPL:DataAPLListe; var AbfrageOK:Boolean);

const
Nicht_ABG_DEL= ' and ((auftrag.nummer=kalkbeschreib.Kalknummer)' +
                        ' and (auftrag.status<>' + #39 + 'ABG' + #39 + ')' +
                        ' and (auftrag.status<>' + #39 + 'DEL' + #39 + ')' +
                        ' and ((kalkbeschreib.status=' + #39 + 'AUF' + #39 + ')' +
                                 ' or (kalkbeschreib.status=' + #39 + 'LIE' + #39 + ')))';


  { Connection string }
  ConnString =
  'Provider=MSDASQL.1;Password=apl;Persist Security Info=True;User ID=apl;Data Source=APLDB Client;Mode=ReadWrite';
    { User access }
  UserName = 'apl';PassWord = 'pass001';Server = 'APLDB Client';

var
  DataModule2test: TDataModule2test;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

Procedure AbfrageAusAPLTest(WhereString:string; var AusAPL:DataAPLListe; var AbfrageOK:Boolean);
// der übergebene Wherestring könnte z.B. lauten: WhereString:=' (Bogenname=' + #39 + Abfrage + #39 + ')';

var
  ADOConn : TADOConnection;
  ADOQuery : TADOQuery;
  //DataSrc : TDataSource;
  //Param   : TParameter;

var SqlString,dummy:string;


begin
  //showmessage('1. in AbfrageAusAPL: '+wherestring);
  (* wenn diese showmessage hier steht, kommt keine Fehlermeldung!!*)
  { Create an ADO connection. }
  ADOConn := TADOConnection.Create(datamodule2test); //self
  { Set up the connection string. }
  ADOConn.ConnectionString := Format(ConnString,[UserName, PassWord, Server]);
  { Disable login prompt. }
  ADOConn.LoginPrompt := False;
  try
    ADOConn.Connected := True; showmessage('connected');
  except
    on e: EADOError do
    begin
      MessageDlg('Error while connecting', mtError,[mbOK], 0);
      Exit;
    end;
  end;
  { Create the query. }
  ADOQuery := TADOQuery.Create(DataModule2test);  //self
  ADOQuery.Connection := ADOConn;
  { Update the parameter that was parsed from the SQL query: AnId. }
 // Param := ADOQuery.Parameters.ParamByName('AnId');
  //Param.DataType := ftInteger;
  //Param.Value := 1;

  { Set the query to Prepared--it will improve performance. }
  ADOQuery.Prepared := true;

  With Datamodule2test do
    begin
          Adoquery.Active:=false;
          //ADOQuery.Close;
          Adoquery.sql.Clear;
          sqlstring:= 'select bogenname,BestellDruckTermin,Farben_BG,BestellLieferTermin,fix,tdruck,twunsch,kalkbeschreib.nummer,' +
                      'f_check,fw_check,Sieb_check, ImDruck_check,Status_PT,auflage19,auflage18,auflage21,auflage20,auflage24,kalkbeschreib.objnummer,' +
                      'text,menge,auflage23,infofrei33,infofrei34,infofrei24,infofrei13,infofrei14,auflage22,besteller' +
                      ' from kalkbeschreib,auftrag where' + WhereString + Nicht_ABG_DEL;
          ADOQuery.sql.Add(sqlstring);
          If TestDB1 then showmessage('sqlstring: '+sqlstring);
            try
              ADOQuery.Active := True;
            except
              on e: EADOError do
              begin
                MessageDlg('Error while doing query', mtError,[mbOK], 0);
                Exit;
              end;
            end;
    end;
end;

end.

hoika 6. Feb 2019 19:21

AW: Fehler bei ADOConnection.Create als DLL
 
Hallo,
Zitat:

2.) Wenn ich die Procedure AbfrageAusAPLTest nicht über eine DLL exportiere, sondern von einem Delphiformular aufrufe, tritt auch mit der Datenbank kein Fehler auf.
Und was ist, wenn ein Delphi-Programm deine DLL benutzt?


Was mit aufgefallen ist,
wo wird das DataModul (datamodule2test) initalisiert?

Zitat:

{ Set the query to Prepared--it will improve performance. }
ADOQuery.Prepared := true;
Wie kommst Du denn darauf ?

Delphi.Narium 6. Feb 2019 19:39

AW: Fehler bei ADOConnection.Create als DLL
 
Von meinen ISAPI-Dlls (aus vergangenen Jahren) weiß ich, dass dashier zwingend erforderlich ist:
Delphi-Quellcode:
unit APLData2test;

uses
  ActiveX;

// alles was Du schon hast

// ganz ans Ende der Unit:

initialization
  // Das wird für ADO dringend benötigt.
  CoInitialize(nil);

finalization
  CoUninitialize;

end.
Bei 'nem Delphiprogramm ist das nicht zwingend erforderlich, da es ggfls. schon "irgendwo anders über Uses ..." implizit aufgerufen wird.

Ob es Dein Problem jetzt konkret behebt, weiß ich nicht, aber 'nen Versuch könnte es wert sein.

martin001 6. Feb 2019 19:55

AW: Fehler bei ADOConnection.Create als DLL
 
Delphi-Quellcode:
library PlanTafelDll_64V2;


uses
  system.sharemem,
  System.SysUtils,
  System.Classes,
  RO_allgemein in '..\..\..\RAD Studio\units\RO_allgemein.pas',
  ro_datum2 in '..\..\..\RAD Studio\units\ro_datum2.pas',
  AplDataAuf in 'AplDataAuf.pas' {DataModule1: TDataModule},
  ausXLS in 'ausXLS.pas',
  Dek_Sam in 'Dek_Sam.pas',
  excel_Sambg in 'excel_Sambg.pas',
  Plantafel in 'Plantafel.pas',
  APLData2test in 'APLData2test.pas' {DataModule2test: TDataModule};

{$R *.res}
exports
GetLongText2,
GetLongText3,
GetNewEntries,
GetSingleEntries,
SetDataToAPL,
Suchauftrag,
PlanWerktagInXTagen,
PlanWerktageDifferenz,
initPlantafel,
Protokol;

initialization
coInitialize(nil);

finalization
coUninitialize;
end;


begin

end.

Wenn ich das so eintrage, kommen folgende Meldungen:
[dcc64 Fehler] PlanTafelDll_64V2.dpr(30): E2029 'BEGIN' erwartet, aber 'INITIALIZATION' gefunden
[dcc64 Fehler] PlanTafelDll_64V2.dpr(31): E2003 Undeklarierter Bezeichner: 'coInitialize'
[dcc64 Fehler] PlanTafelDll_64V2.dpr(34): E2003 Undeklarierter Bezeichner: 'coUninitialize'
[dcc64 Fehler] PlanTafelDll_64V2.dpr(35): E2029 '.' erwartet, aber ';' gefunden
[dcc64 Fehler] PlanTafelDll_64V2.dpr(38): E2004 Bezeichner redeklariert: "Finalization"

martin001 6. Feb 2019 20:03

AW: Fehler bei ADOConnection.Create als DLL
 
Unten habe die Zeilen "initialization" eingefügt. Der Quelltext beantwortet dann vermutlich auch die Frage wo die unit initialisiert wird.
Es kommt folgende Fehlermeldung:
[dcc64 Fehler] PlanTafelDll_64V2.dpr(30): E2029 'BEGIN' erwartet, aber 'INITIALIZATION' gefunden
Ist das die falsche Stelle?



Delphi-Quellcode:
library PlanTafelDll_64V2;


uses
  system.sharemem,
  System.SysUtils,
  System.Classes,
  RO_allgemein in '..\..\..\RAD Studio\units\RO_allgemein.pas',
  ro_datum2 in '..\..\..\RAD Studio\units\ro_datum2.pas',
  AplDataAuf in 'AplDataAuf.pas' {DataModule1: TDataModule},
  ausXLS in 'ausXLS.pas',
  Dek_Sam in 'Dek_Sam.pas',
  excel_Sambg in 'excel_Sambg.pas',
  Plantafel in 'Plantafel.pas',
  APLData2test in 'APLData2test.pas' {DataModule2test: TDataModule};

{$R *.res}
exports
GetLongText2,
GetLongText3,
GetNewEntries,
GetSingleEntries,
SetDataToAPL,
Suchauftrag,
PlanWerktagInXTagen,
PlanWerktageDifferenz,
initPlantafel,
Protokol;

initialization
coInitialize(nil);

finalization
coUninitialize;
end;


begin

end.

Delphi.Narium 6. Feb 2019 20:18

AW: Fehler bei ADOConnection.Create als DLL
 
Das gehört in die unit APLData2test und nicht in die library PlanTafelDll_64V2.

martin001 6. Feb 2019 20:21

AW: Fehler bei ADOConnection.Create als DLL
 
habe ich gerade auch gesehen. Und activeX eingebunden. Funktioniert. Vielen tausend Dank für die Hilfe.


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