AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Fehler

Ein Thema von theomega · begonnen am 5. Dez 2002 · letzter Beitrag vom 5. Dez 2002
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#1

DLL Fehler

  Alt 5. Dez 2002, 15:51
Hallo
jetzt wirds ein bischen ausführlich:

1. eine dll: "deu.dll"

Delphi-Quellcode:
library DEU;

uses
  SysUtils,
  Classes;

{$R *.res}


type TInfo=record
author:shortstring;
name:shortstring;
end;

function info:TInfo;stdcall;

var re:tInfo;
begin;
re.author := 'Dominik Bruhn';
re.name := 'German / Deutsch';

result := re;
end;
//=================================================


type TLanguage=record
opentermset:shortstring;
newtermset:shortstring;
end;

function language:TLanguage; stdcall;
var re:TLanguage;
begin;
re.opentermset := 'Termset öffnen';
re.newtermset := 'Neues Termset';

result := re;
end;



begin

end.
export
language,
info;
ganz simpel. Die eine Funktion soll ein Paar Infos zurückgeben, die andere soll dann nachher recht viele Strings hergeben

dann in meiner Host-Anwendung:
Delphi-Quellcode:
unit functions;

interface

uses ComCtrls,inifiles,SysUtils,Classes,Dialogs,XMLDoc,XMLIntf,Graphics,Controls,Math,Types,windows;

type TInfo=record
author:shortstring;
name:shortstring;
end;

type TLanguage=record
opentermset:shortstring;
newtermset:shortstring;
end;

type
TDlllanguage=function: TLanguage;
TDllinfo=function :TInfo;

procedure loadlanguage(lang:string);
implementation

procedure loadlanguage(lang:string);
var
  mydll : dword;
  Dllinfo : TDLLinfo;
  Dlllanguage: TDlllanguage;

  retinfo:TInfo;
begin;
mydll :=0;
mydll := LoadLibrary(pchar(lang+'.dll');

if(mydll <> 0) then
  begin
  Dllinfo := GetProcAddress(mydll,'info');
  Dlllanguage := GetProcAddress(mydll,'language');

  if(@Dllinfo = nil) or (@Dlllanguage = nil)then
       begin
          FreeLibrary(MyDll);
          MyDll := 0;
  end
end;

if(not (@Dllinfo = nil)) and (MyDll <> 0) then begin;
retinfo := Dllinfo;
end;

if(MyDll <> 0) then
  FreeLibrary(MyDll);
end;
was jetzt eingetlich passieren sollte: in der retinfo sollten jetzt eingetlich die beiden Strings aus der DLL drinstehen. Tun sie aber nicht.

Aus irgendeinem Grund wird in diese Schlaufe verlinkt und damit die DLL wieder geunloaded:
Delphi-Quellcode:
  if(@Dllinfo = nil) or (@Dlllanguage = nil)then
       begin
          FreeLibrary(MyDll);
          MyDll := 0;
  end
Warum ist das so?
Weiß jemand Rat?

Danke

TO


[edit=Admin]Delphi-Tags eingefügt. Mfg. Daniel[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2
  Alt 5. Dez 2002, 16:00
Funktioniert es, wenn Du Deine DLL Deklariationen wie folgt anpasst?

Code:
library DEU;

uses
  SysUtils,
  Classes;

{$R *.res} 


type TInfo=record
author:shortstring;
name:shortstring;
end;

function info:TInfo;stdcall; [color=#ee0000][b]exports;[/b][/color]

var re:tInfo;
begin;
re.author := 'Dominik Bruhn';
re.name := 'German / Deutsch';

result := re;
end;
//=================================================


type TLanguage=record
opentermset:shortstring;
newtermset:shortstring;
end;

function language:TLanguage; stdcall; [color=#ee0000][b]exports;[/b][/color]
var re:TLanguage;
begin;
re.opentermset := 'Termset öffnen';
re.newtermset := 'Neues Termset';

result := re;
end;



begin

end.
export
language,
info;
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3
  Alt 5. Dez 2002, 17:00
Den Record als Result zurückzuliefern ist sehr gewagt. Ein C++/VB Programm kann damit überhaupt nichts anfangen und wird den Speicher auch nicht freigeben, bzw. ihn, da er nicht von selbigem reserviert wurde überschreiben. Ich kenne auch keine WinAPI die einen Record so zurückkliefert.

Eine bessere Deklaration wäre (WinAPI konform):
procedure info(var AInfo: TInfo); stdcall; @sakura: Das export Symbol ist veraltet und nur noch zur Kompatiblität zu älterem Code vorhanden. Es hat keine Bedeutung mehr im 32Bit Zeitalter.


Was am obigen Code fehlt ist der exports Abschnitt:
Delphi-Quellcode:
library xyz;
...
exports
  info,
  language;

end.
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#4
  Alt 5. Dez 2002, 18:45
Der exports teil fehlt bei mir aber nicht!
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#5
  Alt 5. Dez 2002, 18:56
doch tut er

jetzt taucht das nächste Problem auf: Wenn ich alle Debug-Showmessages raus mache, dann passiert garnix. Wenn ich die DLL lösche, dann läuft das Programm wieder. Und wenn ich eine showmessage in die Procedure einbau, wird die auch angezeigt, allerdings ist das Programm dannach wieder weg.

hier nocheinmal der neue DLL-Code:
Code:
library DEU;

uses
  SysUtils,
  Classes;

{$R *.res}


type TInfo=record
author:shortstring;
name:shortstring;
end;

function info:TInfo;stdcall;

var re:tInfo;
begin;
re.author := 'Dominik Bruhn';
re.name := 'German / Deutsch';

result := re;
end;
//=================================================


type TLanguage=record
opentermset:shortstring;
newtermset:shortstring;
end;

function language:TLanguage; stdcall;
var re:TLanguage;
begin;
re.opentermset := 'Termset öffnen';
re.newtermset := 'Neues Termset';

result := re;
end;

exports
language,
info;

begin

end.
die andere Procedure ist gleichgeblieben.

Und nochwas: Das Array ist im Programm nachher leer. Vielleicht habt ihr doch recht. Aber was für andere Möglichkeiten gibt es denn?
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6
  Alt 5. Dez 2002, 19:04
Welches array?

Den Strichpunkt nach begin kannst du dir sparen. Da kommt keiner hin. Aber das ist deine Sache ob du ihn schreibst oder nicht, da er wahrscheinlich schon automatisch da hinkommt
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#7
  Alt 5. Dez 2002, 19:09
ich meine den record
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8
  Alt 5. Dez 2002, 19:28
Ich habe den Fehler gefunden. In deinem Host-Programm hast du das stdcall; vergessen:
Delphi-Quellcode:
  TDllLanguage = function: TLanguage; stdcall;
  TDllInfo = function: TInfo; stdcall;
Aber das mit dem Result := re ist trotzdem etwas wage. Es funktioniert nur, da Delphi mitdenkt (zumindest bei Records) und bei als stdcall deklarieren Funktionen die Adresse der Variable, die das Ergebnis aufnehmen soll, als 1. Parameter übergibt. So würde deine Funktion für ein C/C++ Programm so aussehen:
Code:
void WINAPI info(TInfo* re);
Was natürlich auch für deine Host-Anwendung anwendbar wäre:
Delphi-Quellcode:
TDllInfo = procedure(var re: TInfo); stdcall;
// ist bei stdcall identisch mit
TDllInfo = function: TInfo; stdcall;
  Mit Zitat antworten Zitat
Benutzerbild von theomega
theomega

Registriert seit: 18. Jun 2002
684 Beiträge
 
#9
  Alt 5. Dez 2002, 20:11
Funzt jetzt
aber nocheinmal wegen dem Record. Ich versuche damit meine Anwendung mehrsprachig zu gestalten. Gibt es da andere Möglichkeiten, außerdem (bescheuterten) Sprachtool von Delphi?
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#10
  Alt 5. Dez 2002, 20:43
Moin The Omega,

der Möglichkeiten gibt's da wohl ein paar mehr.
(Das Tool von Borland kenne ich nicht)

Du könntest Dir z.B. Resourcen DLL's bauen, entsprechend benannt werden müssen, und die die jeweiligen lokalisierten Strings als Stringresourcen enthalten. Schlüsselwort: resourcestring.
Ein Beispiel dafür, auch wenn's nicht als DLL sondern als Unit gemacht ist, gibt's in der consts.pas in den VCL Sourcen.

Eine andere Möglichkeit, die es auch anderen ermöglicht Dein Programm zu "übersetzten" wäre eine schlichte Textdatei, ähnlich einer INI.
Dazu könntest Du Dir als Beispiel mal Inno Setup ansehen. Da sind ja viele Leute dabei das Programm zu lokalisieren.

Was die Längen der Strings angeht müsstest Du natürlich in letzterem Falle besonders aufpassen.
Ausserdem wäre es dann vielleicht noch ganz sinnvoll, wenn Du Dir Gedanken über Unicode Unterstützung machen würdest. Nicht alle Sprachen kommen schliesslich mit dem ANSI Zeichensatz aus.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05:44 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