AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

Ein Thema von R2009 · begonnen am 13. Dez 2009 · letzter Beitrag vom 14. Dez 2009
Antwort Antwort
R2009

Registriert seit: 9. Mär 2009
Ort: Heidelberg
440 Beiträge
 
Delphi 2007 Professional
 
#1

Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 13. Dez 2009, 09:39
Hi,
ich versuche eine QT4 erzeugte DLL durch Delphi zu nutzen.
Ich habe eine DLL mit PellesC erzeugt. Mit dieser DLL funktioniert alles (allerdings pures C).
Ich habe den Code nach QT4 umgesetzt und kann ihn kompilieren. Die DLL ist auch vorhanden.
Wenn ich diese aus Delphi aufrufe bekomme´ich Prozedureinstiegspunkt nicht gefunden.
Ich gehe davon aus, dass ich irgendetwas bei der Einstellung in QT4 falsch mache.

Frage: Wie muss ich QT4 einstellen um an eine Delphi konforme DLL zu kommen.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  Mystruct =record
    NumA,NumB,NumC:integer;
    TestA,TestB:shortstring;
    str:shortstring;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    Label2: TLabel;
    Button3: TButton;
    Label3: TLabel;
    Button4: TButton;
    Label4: TLabel;
    Label5: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  function Addit(a, b: integer): integer;stdcall ;
  function Mulit(a, b: integer): integer;stdcall ;
  function stringit(a:char): char;stdcall ;
  function recordes(a:Pointer): integer;stdcall ;

implementation

{$R *.dfm}
function Addit(a, b: integer): integer;stdcall;external 'Qtest.dll'; //cdecl
function Mulit(a, b: integer): integer;stdcall;external 'Qtest.dll'; //cdecl
function stringit(a:char): char;stdcall ;external 'Qtest.dll'; //cdecl
function recordes(a:Pointer): integer;stdcall ;external 'Qtest.dll'; //cdecl

procedure TForm1.Button1Click(Sender: TObject);
begin
  label1.Caption:=inttostr(Addit(2,3));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  label2.Caption:=inttostr(Mulit(2,3));
end;

procedure TForm1.Button3Click(Sender: TObject);
var a:char;
begin
  a:='h';
  label3.Caption:=Stringit(a);
end;

procedure TForm1.Button4Click(Sender: TObject);
var a:^Mystruct;
begin
  new(a);
  a^.NumA:=100;
  a^.NumB:=200;
  a^.NumC:=300;
  a^.TestA:='Test';
  label4.Caption:=inttostr(recordes(@a^));
  label5.caption:=a^.TestB;
  dispose(a);
end;
Nun noch den QT4 Code: (weiss leider nicht wie man C Code formatiert, deshalb als Zitat)

Zitat:
//Pelles C: File-> New-> Project
// Choose Win32 Dynamic Link Library (DLL)
// Enter Test in the Name field
// Set the project path in the Location field

//Project Options-> Compiler
//Check: Use Microsoft extensions
//Check: Undecorate exported __stdcall functions
//Add this file to the project
//Project-> Build Test.dll

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

struct MyStruct
{
int NumA;
int NumB;
int NumC;
char TestA[255];
char TestB[255];
char const* str;
}; // notice the semicolon here

BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
if(Reason==DLL_PROCESS_ATTACH)
{
return TRUE;
}

if(Reason==DLL_PROCESS_DETACH)
{
return TRUE;
}

return FALSE;
}

INT __declspec(dllexport) __stdcall Addit ( int A, int B)
{
int C;
C = A + B;
return C;
}

INT __declspec(dllexport) __stdcall Mulit ( int A, int B)
{
int C;
C = A * B;
return C;
}

char __declspec(dllexport) __stdcall stringit ( char A)
{
return A;
}

int __declspec(dllexport) __stdcall recordes (struct MyStruct *strct)
{
// strct->TestA[1] = 'H';
// strct->TestA[0] = 1;
// strct->str = _strdup(strct->TestA);
// strcpy(strct->TestB,strct->TestA);
strcpy(strct->TestB,"*Hallo");
return strct->NumA;
}

VOID __declspec(dllexport) __stdcall FillStruct (struct Mystruct *strct )
{
// copy some values to the structure that is in the LB program
}
Mir ist schon klar, dass das purer C Code ist, QT4 aber eigentlich für C++ geschrieben ist.
Da ich sehr wenig Erfahrung mit C und C++ habe wäre es nett wenn mir jemand auf die Sprünge helfen könnte.

Noch eine Ergänzung:
Tdump mit der funktionierenden DLL aus PellesC:
Zitat:
Exports from DLL7.dll
5 exported name(s), 5 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00001020 1 0000 Addit
00001080 2 0001 FillStruct
00001030 3 0002 Mulit
00001050 4 0003 recordes
00001040 5 0004 stringit
Tdump mit der funktionierenden DLL aus QT4:
Zitat:
Exports from Qtest.dll
5 exported name(s), 5 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
000012D8 1 0000 _Z10FillStructP8Mystruct@4
00001266 2 0001 _Z5Additii@8
0000127F 3 0002 _Z5Mulitii@8
000012A9 4 0003 _Z8recordesP8MyStruct@4
00001296 5 0004 _Z8stringitc@4
Grüsse
Rainer
Rainer Unger
Mein Profil:
Studium Allgemeine Elektrotechnik TH Darmstadt
Entwicklung von Tools für die Rundsteuer und Zählertechnik.
uP's Atmel Prozessoren (ATmega16,32,88...) in C und Assembler.
  Mit Zitat antworten Zitat
anubis2k5

Registriert seit: 5. Jul 2008
13 Beiträge
 
#2

Re: Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 13. Dez 2009, 12:17
Hallo! Vielleicht solltest du die Funktionen nicht durch ihren Namen sondern über ihren Index ansprechen. Dieser scheint ja zumindest bei beiden DLL-Versionen zu stimmen.
  Mit Zitat antworten Zitat
R2009

Registriert seit: 9. Mär 2009
Ort: Heidelberg
440 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 13. Dez 2009, 15:47
Hi,
scheint etwas schwierig zu sein das Thema. Offensichtlich weiss keiner so genau was da abgeht.

Hab das Problem gelöst:

Statt:
INT __declspec(dllexport) __stdcall Addit ( int A, int B)

muss:

extern "C" __declspec(dllexport) INT Addit ( int A, int B)

In Delphi, beim Aufruf:

function Addit(a, b: integer): integer;cdecl;external 'Qtest.dll'; //cdecl statt stdcall

Fragt mich aber nicht warum! Wenn ich die Aufrufe jedenfalls so ändere bekomme ich die gleichen Einsprungprozeduren wie bei PellesC und es funktioniert auch alles.

Mein nächster Schritt wird jetzt sein eine C++ Klasse in der DLL zu deklarieren und sie von aussen, durch Delphi, zu nutzen.
Ich halte euch auf dem laufenden.

Grüsse
Rainer
Rainer Unger
Mein Profil:
Studium Allgemeine Elektrotechnik TH Darmstadt
Entwicklung von Tools für die Rundsteuer und Zählertechnik.
uP's Atmel Prozessoren (ATmega16,32,88...) in C und Assembler.
  Mit Zitat antworten Zitat
hoika

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

Re: Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 13. Dez 2009, 16:00
Hallo,

du bist auf das "Problem" Name-Mangeling reingefallen.
Jede C-Funktion beginnt mit einem _

int Foo();

wird zu _Foo

Eine c++-Klasse aus Delphi heraus zu benutzen,
funktioniert nicht.


Heiko
Heiko
  Mit Zitat antworten Zitat
R2009

Registriert seit: 9. Mär 2009
Ort: Heidelberg
440 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 14. Dez 2009, 06:13
Hi Hoika,

es funktioniert ja mit den gegebenen Änderungen.
Solange ich extern "C" davorstehen habe klappt das ohne weiters.
Die andere variante funktioniert auch mit _ nicht.

Grüsse
Rainer
Rainer Unger
Mein Profil:
Studium Allgemeine Elektrotechnik TH Darmstadt
Entwicklung von Tools für die Rundsteuer und Zählertechnik.
uP's Atmel Prozessoren (ATmega16,32,88...) in C und Assembler.
  Mit Zitat antworten Zitat
R2009

Registriert seit: 9. Mär 2009
Ort: Heidelberg
440 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Zugriff mit Delphi auf QT4 DLL! Prozedureinstiegspunkt!

  Alt 14. Dez 2009, 06:22
Hi,
so ist das funktionsfähig:
Delphi Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  Mystruct =record
    NumA,NumB,NumC:integer;
    TestA,TestB:shortstring;
    str:shortstring;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    Label2: TLabel;
    Button3: TButton;
    Label3: TLabel;
    Button4: TButton;
    Label4: TLabel;
    Label5: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  function Addit(a, b: integer): integer;cdecl ;
  function Mulit(a, b: integer): integer;cdecl ;
  function stringit(a:char): char;cdecl ;
  function recordes(a:Pointer): integer;cdecl ;

implementation

{$R *.dfm}
function Addit(a, b: integer): integer;cdecl;external 'Qtest.dll'; //cdecl
function Mulit(a, b: integer): integer;cdecl;external 'Qtest.dll'; //cdecl
function stringit(a:char): char;cdecl ;external 'Qtest.dll'; //cdecl
function recordes(a:Pointer): integer;cdecl ;external 'Qtest.dll'; //cdecl

procedure TForm1.Button1Click(Sender: TObject);
begin
  label1.Caption:=inttostr(Addit(2,3));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  label2.Caption:=inttostr(Mulit(2,3));
end;

procedure TForm1.Button3Click(Sender: TObject);
var a:char;
begin
  a:='h';
  label3.Caption:=Stringit(a);
end;

procedure TForm1.Button4Click(Sender: TObject);
var a:^Mystruct;
begin
  new(a);
  a^.NumA:=100;
  a^.NumB:=200;
  a^.NumC:=300;
  a^.TestA:='*Tester';
  label4.Caption:=inttostr(recordes(@a^));
  label5.caption:=a^.TestB;
  dispose(a);
end;

end.
C++ Code mit QT4:

Zitat:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

struct MyStruct
{
int NumA;
int NumB;
int NumC;
char TestA[255];
char TestB[255];
char const* str;
}; // notice the semicolon here

BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
if(Reason==DLL_PROCESS_ATTACH)
{
return TRUE;
}

if(Reason==DLL_PROCESS_DETACH)
{
return TRUE;
}

return FALSE;
}

//INT __declspec(dllexport) __stdcall Addit ( int A, int B)
extern "C" __declspec(dllexport) INT Addit ( int A, int B)
{
int C;
C = A + B;
return C;
}

//INT __declspec(dllexport) __stdcall Mulit ( int A, int B)
extern "C" __declspec(dllexport) INT Mulit ( int A, int B)
{
int C;
C = A * B;
return C;
}

//char __declspec(dllexport) __stdcall stringit ( char A)
extern "C" __declspec(dllexport) char stringit ( char A)
{
return A;
}

//INT __declspec(dllexport) __stdcall recordes (struct MyStruct *strct)
extern "C" __declspec(dllexport) INT recordes (struct MyStruct *strct)
{
// strct->TestA[1] = 'H';
// strct->TestA[0] = 1;
// strct->str = _strdup(strct->TestA);
strcpy(strct->TestB,strct->TestA);
// strcpy(strct->TestB," Rainer Unger");
return strct->NumA;
}

VOID __declspec(dllexport) __stdcall FillStruct (struct Mystruct *strct )
{
// copy some values to the structure that is in the LB program
}
Mir ist klar, dass das C Code ist und nicht so ganz zur C++ Umgebung passt!
Wer es selbst probieren will, ich habs angehängt.
(Der Delphi Teil ist mit D7 geschrieben, der QT Teil mit QT4)
Was mir, zur Zeit, auch noch nicht gefällt ist, dass ich libgcc_s_dw2-1.dll mitliefern muss.
Ich gehe allerdings davon aus, dass das mit QT4 und dem GCC Compiler zusammenhängt.

Grüsse
Rainer
Angehängte Dateien
Dateityp: zip dll_test_454.zip (231,3 KB, 4x aufgerufen)
Dateityp: zip qtest_109.zip (15,7 KB, 3x aufgerufen)
Rainer Unger
Mein Profil:
Studium Allgemeine Elektrotechnik TH Darmstadt
Entwicklung von Tools für die Rundsteuer und Zählertechnik.
uP's Atmel Prozessoren (ATmega16,32,88...) in C und Assembler.
  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 23:01 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