AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Funktionspointerübergabe eines C-Programmes an Delphi-DLL
Thema durchsuchen
Ansicht
Themen-Optionen

Funktionspointerübergabe eines C-Programmes an Delphi-DLL

Ein Thema von Thomas233 · begonnen am 10. Mär 2006 · letzter Beitrag vom 29. Mär 2006
Antwort Antwort
Thomas233

Registriert seit: 20. Feb 2004
Ort: Villach
66 Beiträge
 
Delphi 2005 Personal
 
#1

Funktionspointerübergabe eines C-Programmes an Delphi-DLL

  Alt 10. Mär 2006, 17:56
Hi,

ich habe ein ganz spezielles Problem an dem sowohl C++ sowie Delphi (und d.h. auch teilweise die WinApi) beteiligt ist.

Zuerst einmal die Problemstellung:
Von einem C-Programm aus rufe ich eine von mir mit Delphi erstellte Dll auf.
Das funktioniert soweit ganz gut, aber in der Dll gibt es eine Funktion die auf ein Ereignis reagieren soll und dann dieses Ereignis an eine Funktion im C-Programm weitergeben soll (Callback).
Das ganze mache ich derzeit so das ich der Dll über eine Funktion einen Funktionspointer übergebe welche die Dll dann im Ernstfall aufrufen soll (im C-Programm).

Leider klappt das nicht da ich so immer eine Zugriffsverletzung kriege.

Ich denke mal das Problem ist die Übergabe des Funktionspointers, kann aber natürlich auch woanders liegen (es lässt sich ja leider nicht so einfach debuggen).

Zur Veranschaulichung hier die wichtigsten Ausschnitte beider Codes (bei dem ganzen handelt es sich übrigens um eine teilweise Auslagerung der VCL in eine Dll):

Delphi-Quellcode:
//Delphi Code
//DLL

//...

//Konstanten
const VCLA_CLOSE=$aa;
const VCLA_CLICK=$ab;
const VCLA_DBLCLICK=$ac;
const VCLA_CHANGE=$ad;

//Globale Deklarationen
var Controls:TObjectList; //Alle VCL-Controls
var ControlsAliases:TStringlist; //Hier werden die Namen der Controls gespeichert (zur Zuordnung von Ids)
var ctrlsEventCallbackFunc:TList; //Pointer auf die Callback-Funktionen
var EventHandlerInst:TVCLAdaptEventHandler; //Event-Handler, mit den Methoden in dieser Klasse werden die Callback-Funktionen aufgerufen

type StandardEventCallback=procedure(_ctrlname:PChar;action:integer;_value:PChar); stdcall; //Das ist die Deklaration der Callback-Funktion im C-Programm
type pStandardEventCallback=^StandardEventCallback;

function SetCallback(_ctrlname:PChar;var _callbfunc:pStandardEventCallback):integer; stdcall; export; //Hiermit wird so eine Callbackfunktion "registriert"
var tmpid:integer;
begin
Result:=0;

if (ControlsAliases<>nil) and (ctrlsEventCallbackFunc<>nil) then begin
  tmpid:=ctrlsEventCallbackFunc.Add(_callbfunc); //Pointer auf die Callback-Funktion im C-Programm wird in die zugehörige-Liste eingetragen

  ControlsAliases.Add(_ctrlname); //Der Name des zugehörigen Controls wird ebenfalls gespeichert
end
else
  Result:=-1;
end;

function GetEventCallbFuncFromLists(_ctrlname:PChar):pStandardEventCallback; //Findet heraus ob eine Callback-Funktion zum angegebenen Control existiert und liefert den Pointer auf die Callback-Funktion zurück
var tmpid:integer;
begin
if (ControlsAliases<>nil) and (ctrlsEventCallbackFunc<>nil) then begin
  tmpid:=ControlsAliases.IndexOf(_ctrlname); Sucht die Id in der Callback-Pointer-Liste heraus (anhand des Control-Namens)

  if tmpid>-1 then
    Result:=ctrlsEventCallbackFunc[tmpid];
end
else
  Result:=nil;
end;

procedure TVCLAdaptEventHandler.CloseEventHandler(_sender:TObject;var _action:TCloseAction);
var tmpCallbFunc:pStandardEventCallback; //Diese Funktion springt bei Bedarf in die Callback-Funktion im C-Programm
begin
tmpCallbFunc:=GetEventCallbFuncFromLists(PChar(TControl(_sender).Name)); //s.o.

if tmpCallbFunc<>nil then //Wenn Callback-Funktion gefunden
  tmpCallbFunc^(PChar(TControl(_sender).Name),VCLA_CLOSE,PChar(nil)); //Aufruf der Callback-Funktion im C-Programm, ich glaube HIER kommt es zum Fehler!
end;

//...
Code:
//C++ Code
//Hauptprogramm (Win32)

//Folgendes steht in einer Header
//...
#define VCLA_CLOSE 0xaa;
#define VCLA_CLICK 0xab;
#define VCLA_DBLCLICK 0xac;
#define VCLA_CHANGE 0xad;

typedef int (__stdcall *VCLADAPTSetCallback)(char*,void*); //Die SetCallback Methode in der Dll

VCLA_SetCallback = (VCLADAPTSetCallback)GetProcAddress(h_VCLA_DLL,"SetCallback"); //Nachdem die Dll geladen wurde wird die SetCallback-Methode ebenfalls geladen (ist nicht NULL !!)

//...

//In Haupt-Cpp-Datei
void __stdcall CALLBACK AppCall(char* _ctrlname,int _action,char* _val) //Dies ist so eine Callback-Funktion die aus der Dll heraus aufgerufen werden sollte
{
         //...
   PostQuitMessage(0);
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

MSG wmsg;

//...

VCLA_SetCallback(test,AppCall);

while(GetMessage(&wmsg,NULL,0,0))
   {
      TranslateMessage(&wmsg);
      DispatchMessage(&wmsg);
   }
   return wmsg.wParam;

//return 0;


//ENDE
So, das ganze ist ein bissle kompliziert, ich hoffe aber das einer von euch vielleicht das Problem findet.

Wäre jedenfalls echt toll !

Vielen Dank im Vorraus,
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: Funktionspointerübergabe eines C-Programmes an Delphi-DL

  Alt 10. Mär 2006, 22:56
Ich rate jetzt mal ins Blaue, da ich mein Delphi nicht mehr offen habe: "StandardEventCallback" ist selbst schon ein Funktionszeiger, "pStandardEventCallback" wäre ein Zeiger auf einen solchen Zeiger. Von C aus übergibst du aber einen einfachen Zeiger. Mit "tmpCallbFunc^" rufst du daher nicht die Prozedur auf sondern versuchst von der Prozeduradresse selbst einen Prozedurzeiger zu lesen.

Benutze also "StandardEventCallback" statt "pStandardEventCallback" und ändere dann an den Stellen mit Compilerfehlern den Zugriff von "x <> nil" auf "Assigned(x)" oder "@x <> nil".
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Thomas233

Registriert seit: 20. Feb 2004
Ort: Villach
66 Beiträge
 
Delphi 2005 Personal
 
#3

Re: Funktionspointerübergabe eines C-Programmes an Delphi-DL

  Alt 11. Mär 2006, 13:28
Hi,

ich glaube du könntest Recht haben (hab schon irgendwo mal so etwas gesehen) aber entweder der Fehler liegt woanders oder ich krieg das nicht hin.

Hier die geänderten Funktionen:
Delphi-Quellcode:
function SetCallback(_ctrlname:PChar;var _callbfunc:StandardEventCallback):integer; stdcall; export;
var tmpid:integer;
begin
Result:=0;

if (ControlsAliases<>nil) and (ctrlsEventCallbackFunc<>nil) then begin
  tmpid:=ctrlsEventCallbackFunc.Add(@_callbfunc);

  ControlsAliases.Add(_ctrlname);
end
else
  Result:=-1;
end;

function GetEventCallbFuncFromLists(_ctrlname:PChar):StandardEventCallback;
var tmpid:integer;
begin
if (ControlsAliases<>nil) and (ctrlsEventCallbackFunc<>nil) then begin
  tmpid:=ControlsAliases.IndexOf(_ctrlname);

  if tmpid>-1 then
    Result:=ctrlsEventCallbackFunc[tmpid];
end
else
  Result:=nil;
end;

procedure TVCLAdaptEventHandler.CloseEventHandler(_sender:TObject;var _action:TCloseAction);
var tmpCallbFunc:StandardEventCallback;
begin
tmpCallbFunc:=GetEventCallbFuncFromLists(PChar(TControl(_sender).Name));

if Assigned(tmpCallbFunc) then
  tmpCallbFunc(PChar(TControl(_sender).Name),VCLA_CLOSE,PChar(nil));
end;
Ich bin mir nicht sicher ob ich alles richtig umgeändert habe, vor allem bei der Funktion "GetEventCallbFuncFromLists".

Muss ich im C-Programm auch etwas ändern ?

Vielen Dank erstmal für deine Hilfe !

Mit freundlichen Grüßen,
Thomas
  Mit Zitat antworten Zitat
Thomas233

Registriert seit: 20. Feb 2004
Ort: Villach
66 Beiträge
 
Delphi 2005 Personal
 
#4

Re: Funktionspointerübergabe eines C-Programmes an Delphi-DL

  Alt 29. Mär 2006, 23:05
So, das Problem wurde inzwischen gelöst, war eine ganz gemeiner Logikfehler irgendwo anders.

However, wie so oft entstand inzwischen ein neues Problem, bei dem ich nicht weiter weiss:
http://www.delphipraxis.net/internal...ct.php?t=79372

Danke an alle fleissigen Helferlein (@Flocke) !
  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 22:10 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