Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi C++ DLL in Delphi einbinden (https://www.delphipraxis.net/25097-c-dll-delphi-einbinden.html)

runger 1. Jul 2004 05:59


C++ DLL in Delphi einbinden
 
Hallo,
ich habe folgendes Problem:
ich möchte eine in C++ geschriebene DLL in Delphi benutzen.
Die Deklaration der einzigen Funktion ist bekannt:

Code:
- int versacom(TRAB *tr, char * otrailer),
- TRAB Struktur:

TRAB    {
           int       prio;                   
   int   typ;            
   int   optim,             
             repeat,                                   service,               
      tel_hie,            
                  group_tra;            
      int    station;
            AVER   aver;               
AVERI   averi;                         
   long   duration;         
   char   value[6];                
   int   tostate,                
                   tipair,                 
                   pronum,                 
                   ontime,                
                   offtime;
           char   b1;            
           int   promask,
                   wkday,
      time_cycle,
                   fun;
   char   loadtel[26],         
      lt_ntrail[26],          
      msg[70],          
      msg_bin[200];          

- AVER und AVERI Struktur:

AVER { 
   uchar   region,
            section[4],
      class[2],
      division[2];
      };

AVERI { 
   long   senu;
   int   relay;   
      };
In Delphi hab ich die Typdeklarationen so festgelegt:

Delphi-Quellcode:
type
  AVER=record
    region:char;
    section:string[4];
      clas:string[2];
      division:string[2];
  end;

  AVERI=record
   senu:longint;
   relay:integer;
  end;

  TRAB=record
     prio:integer;      
     typ:integer;                   
     optim:integer;    
     repeate:integer;
     service:integer;               
     tel_hie:integer;      
     group_tra:integer;           
     station:integer;
     aver:aver;                 
     averi:averi;         
     duration:longint;            
     value:string[6];            
     tostate:integer;         
     tipair:integer;
     pronum:integer;    
     ontime:integer;  
     offtime:integer;
     b1:char;   
     promask:integer;
     wkday:integer;
     time_cycle:integer;
     fun:integer;
     loadtel:string[26];          
     lt_ntrail:string[26];         
     msg:string[70];              
     msg_bin:string[200];
end;
Nun gibts zwei Probleme:

1.) Wenn ich versuche die Funktion zu deklarieren nimmt er nur einen Parameter.

2.) Ich bekomme was ich auch tue eine Zugriffsverlezung.

Weiss jemand weiter?

Rainer

Luckie 1. Jul 2004 06:02

Re: C++ DLL in Delphi einbinden
 
Könntest du mal bitte die Tabs im oberen Code duch Leerzeichen ersetzten? Dann kann man das auch lesen.

Robert Marquardt 1. Jul 2004 06:06

Re: C++ DLL in Delphi einbinden
 
Poste mal das .h file hier und zwar ohne Tabulatoren und vollstaendig.

string[xx] ist nicht gut. Nimm array [0..xx-1] of Char.

Was soll 1. denn heissen?

2. bedeutet das die Struktur nicht die richtige Groesse hat. Das packicng der Elemente ist auch noch nicht geklaert.
Die calling convention (cdecl oder stdcall) muss bestimmt werden.

runger 1. Jul 2004 06:19

Re: C++ DLL in Delphi einbinden
 
Hallo tut mir leid, dass das so unformatiert aussah, konnte ich aber leider nicht sehen.

Code:
- int versacom(TRAB *tr, char * otrailer),
- TRAB Struktur:

TRAB   { 
   int       prio;                    
   int  typ;            
   int  optim,repeat,service,tel_hie,group_tra;
   int    station;
   AVER  aver;              
   AVERI  averi;                        
   long  duration;        
   char   value[6];                
   int  tostate,tipair,pronum,ontime,offtime;
   char  b1;            
   int  promask,wkday,time_cycle, fun;
   char  loadtel[26],lt_ntrail[26],msg[70],msg_bin[200];        

- AVER und AVERI Struktur:

AVER { 
     uchar  region,section[4],class[2],division[2];
      };

AVERI { 
   long  senu;
   int  relay;  
      };
Das Problem ist: ich habe weder den Quellcode noch sonst irgendwelche Informationen über diese DLL muss aber damit arbeiten.

Rainer

Dax 1. Jul 2004 06:23

Re: C++ DLL in Delphi einbinden
 
Wenn der Inhalt der Records bekannt ist, dann deklarier die eine Funktion doch so:

Delphi-Quellcode:
type
  PTRAB = ^TRAB;

function versacom(tr: PTRAB; otrailer: PChar): integer; external [DLLName]+'.dll' name 'versacom';
Bei geht so was immer.
Oder du benutzt LoadLibrary und GetFuntionEntryPoint oder wie das auch alles heissen mag.

Robert Marquardt 1. Jul 2004 06:27

Re: C++ DLL in Delphi einbinden
 
Na dann deklariere erst mal alle arrays wie ich es angegeben habe.
Die records sind wahrscheinlich packed record.
uchar sollte als Byte uebersetzt werden.

Delphi-Quellcode:
function versacom(var tr: TRAB; otrailer: PChar): Integer; stdcall;
Das ist die wahrscheinlichste Deklaration fuer die Funktion.

runger 2. Jul 2004 06:20

Re: C++ DLL in Delphi einbinden
 
Hallo,

den Funktionsaufruf hab ich jetzt!
Das prog wurschtelt auch in der DLL rum. Irgendwann bekomme ich die Exception: access violation at 0x00000000...

Stimmen die Übergabestrukturen nicht?
Was ist mit den C++ Typen?

C++ D7
-------------------------
int integer
long longint

stimmt das?
Im Internet steht darüber einmal das und einmal das.
Robert, ich habe alles was du vorgeschlagen hast umgesetzt.

Vielen Dank im vorraus
Rainer

Stevie 2. Jul 2004 07:33

Re: C++ DLL in Delphi einbinden
 
Das müsste so stimmen. Kennst du schon das Dll-Tutorial von Assarbad? Dort gibt es auch eine umfangreiche der Datentypen.

Muetze1 2. Jul 2004 08:22

Re: C++ DLL in Delphi einbinden
 
Moin!

Kann es sein, das du Speicher für den PChar alloziieren musst? Stichwort StrAlloc()...

MfG
Muetze1

neolithos 2. Jul 2004 09:33

Re: C++ DLL in Delphi einbinden
 
Der C char[2] (2 Byte) ist ungleich dem Pascal String[2] (3 Byte).

Ich würde die Strukturen nochmal prüfen.

shmia 2. Jul 2004 09:48

Re: C++ DLL in Delphi einbinden
 
Zitat:

Zitat von Muetze1
Kann es sein, das du Speicher für den PChar alloziieren musst? Stichwort StrAlloc()...

Mit Sicherheit muss man das tun.
Delphi-Quellcode:
var
   otrailer : string;
   tr: TRAB;
   erg : integer;
begin
   // record tr mit Daten füllen
   ....
   // Speicher für otrailer anlegen
   SetLength(otrailer, 1000);   // das sollte reichen  

   erg := versacom(tr, PChar(otrailer)); // der Aufruf

   // string otrailer verkürzen bis zum 1. Auftreten von #0
   otrailer := PChar(otrailer);

   // Auswertung von erg nicht vergessen !
end;

Muetze1 2. Jul 2004 11:02

Re: C++ DLL in Delphi einbinden
 
Moin!

Ich meine ebend nicht diesen TypeCast, da der bei der Weitergabe an die DLL Probleme machen kann (und bei mir auch meistens macht), daher habe ich nicht umsonst auf StrAlloc() verwiesen. Alloziiere den PChar mit StrAlloc()...

MfG
Muetze1

Stevie 2. Jul 2004 11:11

Re: C++ DLL in Delphi einbinden
 
Das Problem liegt ja in der Sache an sich:
- string[0] gibt ja die Länge des Strings und bracuht somit kein Abschlusszeichen
- bei pchar geht der String bis zum Auftreten des Abschlusszeichens

shmia 2. Jul 2004 12:55

Re: C++ DLL in Delphi einbinden
 
Zitat:

Zitat von Muetze1
Ich meine ebend nicht diesen TypeCast, da der bei der Weitergabe an die DLL Probleme machen kann (und bei mir auch meistens macht), daher habe ich nicht umsonst auf StrAlloc() verwiesen. Alloziiere den PChar mit StrAlloc()...

StrAlloc gehört zu den backward compatibility routines.
Dagegen ist die Vorgehensweise, die ich vorgeschlagen habe "Delphi-Like".
Es wird mit SetLength dynamisch Speicher reserviert. Denoch braucht sich der
Programmierer nicht um die Freigabe des Speichers zu kümmern.
Man darf bedenkenlos einen Zeiger auf den reservierten String in eine externe Funktion hineingeben und darauf vertrauen, dass die Funktion auf den Zeiger schreiben darf (solange die Länge nicht überschritten wird).
Allerdings hätte ich vielleicht dazu sagen müssen, dass nur AnsiStrings erlaubt sind:
Delphi-Quellcode:
var
   otrailer : AnsiString; // (auch als langer String bezeichnet)


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