Einzelnen Beitrag anzeigen

Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#1

Problem mit dynamischen dll´s

  Alt 11. Mär 2011, 20:50
Hi,

ich komme gerade bei einem kleinen Problem nicht wirklich weiter.

Ich habe ein Konstrukt aufgebaut das so aussieht:

Programm <-> Globale Dll <-> Plugin Dll

Die Global Dll ist dabei statisch im Programm eingebunden und die Plugin Dll wird wiederum von der Dlobal Dll dynamisch geladen.

So sieht der Code aus:

Programm:
Code:
unit Unit1;

.
.
.

function GlobalPlugin_show_optionwindow(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_show_about(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_show_additionalwindow(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_init(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_free(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_LoadPlugin(PluginName: string): boolean; stdcall; external 'GlobalPlugin.dll';

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  GlobalPlugin_init;
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
  GlobalPlugin_LoadPlugin(cbb1.Text);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  GlobalPlugin_free;
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  GlobalPlugin_Show_about;
end;

end.
Code der GlobalPlugin.dll
Code:
// Dll Import



function GlobalPlugin_Send_Cue(slave_id, kanal: Integer): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_Send_Value(value: Integer): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_show_optionwindow(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_show_about(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_show_additionalwindow(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_init(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_free(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_LoadPlugin(PluginName: string): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_Connect(com_port: word): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_Disconnect(): boolean; stdcall; external 'GlobalPlugin.dll';
function GlobalPlugin_Com_Status(): boolean; stdcall; external 'GlobalPlugin.dll';




library GlobalPlugin;

uses
  ShareMem, Windows, SysUtils, Classes, dialogs, StrUtils;

type

  T_Plugin_init = function(): Boolean; stdcall;
  T_Plugin_free = function(): Boolean; stdcall;
  T_Plugin_show_optionwindow = function(): Boolean; stdcall;
  T_Plugin_show_about = function(): Boolean; stdcall;
  T_Plugin_show_additionalwindow = function(): Boolean; stdcall;


{$R *.res}

var
  Handle: THandle;


function Plugin_init(): boolean;
var
  Plugin_init: T_Plugin_init;
begin
  if Handle <> 0 then
  begin
    @Plugin_init := GetProcAddress(Handle, 'Plugin_init');
    if @Plugin_init <> nil then
    begin
      result := Plugin_init;
    end;
  end;
end;

function Plugin_free(): boolean;
var
  Plugin_free: T_Plugin_free;
begin
  if Handle <> 0 then
  begin
    @Plugin_free := GetProcAddress(Handle, 'Plugin_free');
    if @Plugin_free <> nil then
    begin
      result := Plugin_free;
    end;
  end;
end;


// Exports


function GlobalPlugin_free(): boolean; stdcall;
begin
  try

    if Handle <> 0 then
    begin
      Plugin_free;
      FreeLibrary(Handle);
    end;

    ComPort.Open := false;
    ComPort.Free;

    result := true;
  except
    result := false;
  end;
end;

function GlobalPlugin_LoadPlugin(PluginName: string): boolean; stdcall;
begin
  if Handle <> 0 then
  begin
    Plugin_free;
    FreeLibrary(Handle);
  end;

  try
    Handle := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + '/Plugins/' + PluginName));
    Plugin_init;

    result := true;
  except
    result := false;
  end;
end;

function GlobalPlugin_show_optionwindow(): boolean;
var
  Plugin_show_optionwindow: T_Plugin_show_optionwindow;
begin
  if Handle <> 0 then
  begin
    @Plugin_show_optionwindow := GetProcAddress(Handle, 'Plugin_show_optionwindow');
    if @Plugin_show_optionwindow <> nil then
    begin
      result := Plugin_show_optionwindow;
    end;
  end;
end;

function GlobalPlugin_show_about(): boolean;
var
  Plugin_show_about: T_Plugin_show_about;
begin
  if Handle <> 0 then
  begin
    @Plugin_show_about := GetProcAddress(Handle, 'Plugin_show_about');
    if @Plugin_show_about <> nil then
    begin
      result := Plugin_show_about;
    end;
  end;
end;

function GlobalPlugin_show_additionalwindow(): boolean;
var
  Plugin_show_additionalwindow: T_Plugin_show_additionalwindow;
begin
  if Handle <> 0 then
  begin
    @Plugin_show_additionalwindow := GetProcAddress(Handle, 'Plugin_show_additionalwindow');
    if @Plugin_show_additionalwindow <> nil then
    begin
      result := Plugin_show_additionalwindow;
    end;
  end;
end;



// Globale Hilfsfunktionen

exports
  GlobalPlugin_LoadPlugin,
  GlobalPlugin_show_optionwindow,
  GlobalPlugin_show_about,
  GlobalPlugin_show_additionalwindow,
  GlobalPlugin_free;

begin
end.
und der Code des Plugin:
Code:
unit MainU;

interface

uses
  ShareMem, SysUtils, Classes, Windows,
  Forms, About_window, Optional_Window, Dialogs;

function Plugin_init(): boolean; stdcall;
function Plugin_free(): boolean; stdcall;
function Plugin_show_optionwindow(): Boolean; stdcall;
function Plugin_show_about(): Boolean; stdcall;
function Plugin_show_additionalwindow(): Boolean; stdcall;

implementation

var
  Optionalwindow: TForm2;
  Aboutwindow: TForm1;


// Dll Export Functions

function Plugin_init(): Boolean; stdcall;
begin
  try
    Optionalwindow := TForm2.Create(Application);
    Aboutwindow := TForm1.Create(Application);

    result := true;
  except
    result := false;
  end;
end;

function Plugin_free(): Boolean; stdcall;
begin
  try
    Optionalwindow.Free;
    Aboutwindow.Free;

    result := true;
  except
    result := false;
  end;
end;

function Plugin_show_optionwindow(): Boolean; stdcall;
begin
   //// Nicht vorhanden
end;

function Plugin_show_about(): Boolean; stdcall;
begin
  Aboutwindow.ShowModal;
end;

function Plugin_show_additionalwindow(): Boolean; stdcall;
begin
  Optionalwindow.Show;
end;


end.
Problem ist folgendes. Wenn ich das Plugin wechsel, sprich in der Comobox ein andere Plugin auswähle und den Button mit "GlobalPlugin_LoadPlugin(cbb1.Text)" klicke, friert das Programm ein.

Beim beenden hängt es sich auch grundsätzlich auf.

Wo kann der Fehler liegen ?

Gruß Yannic
  Mit Zitat antworten Zitat