AGB  ·  Datenschutz  ·  Impressum  







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

Delphi's Interfaces in C++

Ein Thema von Desmulator · begonnen am 1. Jun 2009 · letzter Beitrag vom 1. Jun 2009
Antwort Antwort
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#1

Delphi's Interfaces in C++

  Alt 1. Jun 2009, 09:45
Gute Morgen alle zusammen,

angesichts der Tatsache, das ich eine geschrieben DLL testen muss, habe ich einen Punkt erreicht indem ich mit meinen nahezu nichtigen C++ Kenntnissen nicht mehr weiter komme. Also ich habe meine selbst geschriebene DLL bereits mit mehrern Delphiversionen und auch Lazarus, FreePascal, getestet. Alles läuft wunder bar. Daher habe ich mit dran gesetzt und wollte die header nach C++ überführen. Klappte auch ganz gut, zumindest bei den records bzw. structs und den enums. Bei "set's" habe ich einfe Konstanten benutzt ( wie manns kennt 1, 2, 4, 8, ... ). So dann kamen die Funktione. Da gab es ja schon etwas mehr aufwand, allerdings konnte ich nach langem suchen ein DLL2Lib Programm finden, wodurch das alles wieder recht einfach wurde. Alles super, Daumen hoch. Doch dann, dann kamen die COM-Interfaces.

Ich benutze für C++ das FreeWare Programm Dev-C++, welches mir von einem Kumpel empfohlen wurde. Nun habe ich mir die DirectX-Headers mal angegukt und nachgesehen wie dort die Interfaces beschrieben wurden. Ich übernahm den Aufbau und passte ihn an mein Interface an. Doch dann wurde ich vom Compiler bestraft, es fehle eine vtable für das Interface.

Wo bzw. Wie bekomme ich die vtable?
Muss ich Interfaces etwa auch auf die Exportliste stellen?
Gibt es gute Tools für D2C?

Mfg Desmu
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 10:26
Eigentlich sollte ein Interface in C++ eine Klasse ohne Felder sein, deren Methoden alle abstrakt (pure virtual) sind. Außerdem sollte die Klasse von IUnknown abgeleitet sein. Kannst du mal zeigen, wie es zur Zeit aussieht?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#3

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 11:04
DelphiUnit
Delphi-Quellcode:
unit BaseEngine;

interface

type
  TBaseResult = Cardinal;
  TBaseHandle = Cardinal;

  TBaseDateMonth = 1..12;
  TBaseDateDay = 1..31;
  TBaseTimeHour = 0..23;
  TBaseTimeMinute = 0..59;
  TBaseTimeSecond = 0..59;

  TBaseDateTime = record
    Year : Word;
    Month: TBaseDateMonth;
    Day : TBaseDateDay;
    Hour : TBaseTimeHour;
    Minute : TBaseTimeMinute;
    Second : TBaseTimeSecond;
  end;

  TBaseDate = record
    Year : Word;
    Month: TBaseDateMonth;
    Day : TBaseDateDay;
  end;

  TBaseTime = record
    Hour : TBaseTimeHour;
    Minute : TBaseTimeMinute;
    Second : TBaseTimeSecond;
  end;

  TBaseFileAttribute = ( bfaArchive, bfaDirectory, bfaHidden, bfaReadOnly, bfaSystem, bfaTemporary, bfaCompressed, bfaOffline, bfaNotContentIndexed, bfaEncrypted );
  TBaseFileAttributes = record
    Archive : Boolean;
    Hidden : Boolean;
    Readonly : Boolean;
    System : Boolean;
    Temporary : Boolean;
    Offline : Boolean;
    NotContentIndexed : Boolean;
    { Not changeable }
    Directory : Boolean;
    Compressed : Boolean;
    Encrypted : Boolean;
  end;

  TBaseFileOpenMethod = ( bfomClear, bfomOpen, bfomOpenExisting );
  TBaseFileAccess = set of ( bfaRead, bfaWrite );
  TBaseFileShare = set of ( bfsRead, bfsWrite, bsfDelete );

type
  IBaseInterface = interface(IInterface)
    function GetHandle : Pointer; stdcall;
  end;

  IBaseStream = interface(IBaseInterface)
    function GetSize : Cardinal; stdcall;
    function GetPosition : Cardinal; stdcall;
    function SetPosition(NewPosition : Cardinal) : Boolean; stdcall;
    function Seek(By : Integer) : Boolean; stdcall;

    function Read(var Buffer; Len : Cardinal) : Boolean; stdcall;
    function Write(var Buffer; Len : Cardinal): Boolean; stdcall;

    function Assign(Stream : IBaseStream) : Boolean; stdcall;
    function WriteTo(Stream : IBaseStream) : Boolean; stdcall;
  end;

  IBaseIOStream = interface(IBaseStream)
  end;

  IBaseFileInfo = interface;

  IBaseFile = interface(IBaseIOStream)
    function GetFileInfo(Extended : Boolean) : IBaseFileInfo; stdcall;
  end;

  IBaseFileInfo = interface(IBaseInterface)
    function GetFullPath : PChar; stdcall;
    function GetRelativPath : PChar; stdcall;

    function ExtendInformation : Boolean; stdcall;
    function ReduceInformation : Boolean; stdcall;

    function GetAttributes : TBaseFileAttributes; stdcall;
    function GetAttribute(Attribute : TBaseFileAttribute) : Boolean; stdcall;
    function SetAttributes(AttributeBlock : TBaseFileAttributes) : Boolean; stdcall;
    function SetAttribute(Attribute : TBaseFileAttribute; Value : Boolean) : Boolean; stdcall;

    function GetCreateTime : TBaseDateTime; stdcall;
    function GetLastAccessTime : TBaseDateTime; stdcall;
    function GetLastWriteTime : TBaseDateTime; stdcall;
  end;

const
  BASE_INVALID_HANDLE : TBaseHandle = $FFFFFFFF;
  BaseEngineDll = 'BaseEngine.dll';

function BaseVersion : PChar; stdcall; external BaseEngineDll;
function BaseRevision : PChar; stdcall; external BaseEngineDll;
function BaseCompiled : PChar; stdcall; external BaseEngineDll;
function BaseGetErrorStr(Value : TBaseResult) : PChar; stdcall; external 'BaseEngine.dll';
function BaseGetLastErrorStr(Error : PCardinal) : PChar; stdcall; external 'BaseEngine.dll';
function BaseGetLastError : TBaseResult; stdcall; external 'BaseEngine.dll';
function BaseCloseHandle(Handle : TBaseHandle) : Boolean; stdcall; external 'BaseEngine.dll';
function BaseTimeTickCreate : TBaseHandle; stdcall; external 'BaseEngine.dll';
function BaseTimeTickGap(Handle : TBaseHandle) : Cardinal; stdcall; external 'BaseEngine.dll';
function BaseTimeTick(Handle : TBaseHandle) : Cardinal; stdcall; external 'BaseEngine.dll';
function BaseTimeTickPerSec(Handle : TBaseHandle) : Cardinal; stdcall; external 'BaseEngine.dll';
function BaseTimeTickReset(Handle : TBaseHandle) : Boolean; stdcall; external 'BaseEngine.dll';
function BaseCreateFile(FileName : PChar; OpenMethod : TBaseFileOpenMethod; Access : TBaseFileAccess; ShareMode : TBaseFileShare) : IBaseFile; stdcall; external 'BaseEngine.dll';

implementation

end.
C++ Equivalent
Code:
#include <windows.h>

typedef HRESULT TBaseResult;
typedef UINT TBaseHandle;


// Date & Time Records
typedef struct BaseDateTime {
    WORD Year;
    BYTE Month;
    BYTE Day;
    BYTE Hour;
    BYTE Minute;
    BYTE Second;
} TBaseDateTime;

typedef struct BaseDate {
    WORD Year;
    BYTE Month;
    BYTE Day;
} TBaseDate;

typedef struct BaseTime {
    BYTE Hour;
    BYTE Minute;
    BYTE Second;
} TBaseTime;


// FileAttributes and so on
typedef enum {
    bfaArchive,
    bfaDirectory,
    bfaHidden,
    bfaReadOnly,
    bfaSystem,
    bfaTemporary,
    bfaCompressed,
    bfaOffline,
    bfaNotContentIndexed,
    bfaEncrypted
} TBaseFileAttribute;

typedef struct BaseFileAttributes {
    bool Archive;
    bool Hidden;
    bool Readonly;
    bool System;
    bool Temporary;
    bool Offline;
    bool NotContentIndexed;
    bool Directory;
    bool Compressed;
    bool Encrypted;
} TBaseFileAttributes;

// FileEnums, like share options
typedef enum {
    bfomClear,
    bfomOpen,
    bfomOpenExisting  
} TBaseFileOpenMethod;

// Pascals "set of" is not avaible
#define bfaRead UINT(1)
#define bfaWrite UINT(2)

#define bfsRead UINT(1)
#define bfsWrite UINT(2)
#define bfsDelete UINT(4)

/*interface DECLSPEC_UUID("D4C2BA04-9C15-4631-8774-5AE2E05EBB80") IBaseInterface;
typedef interface IBaseInterface;

#undef INTERFACE
#define INTERFACE IBaseInterface
DECLARE_INTERFACE_(IBaseInterface, IUnknown)
{
    __stdcall void* GetHandle;
    STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj);
    STDMETHOD_(ULONG,AddRef)(THIS);
    STDMETHOD_(ULONG,Release)(THIS);
};
typedef struct IBaseInterface;*/ // Entfernt, weil fehlerhaft. vTable nicht gefunden


extern "C" {
     __declspec(dllimport) char* BaseVersion(); // Weitere Funktionen aus "kB"-Gründen erstmal noch nicht eingebaut.
}
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 11:13
Wo kommen diese Makros DECLARE_INTERFACE_ und STDMETHOD her?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#5

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 11:22
Code:
# define STDMETHODCALLTYPE   __stdcall
#  define STDMETHOD(m)   virtual HRESULT STDMETHODCALLTYPE m
..
#  if defined(__GNUC__) && __GNUC__ < 3 && !defined(NOCOMATTRIBUTE)
#   define DECLARE_INTERFACE(i) interface __attribute__((com_interface)) i
#   define DECLARE_INTERFACE_(i,b) interface __attribute__((com_interface)) i : public b
#  else
#   define DECLARE_INTERFACE(i) interface i
#   define DECLARE_INTERFACE_(i,b) interface i : public b
#  endif
Das erhalte ich zumindest, wenn ich mit gedrückter Strg-Taste drauf klicke.
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 11:33
Ich wusste gar nicht, dass C das Schlüsselwort Interface kennt. Ich hätte das Interface spontan so übersetzt:
Code:
class IBaseInterface: public IUnknown
{
    virtual __stdcall void* GetHandle() = 0;
}
Meine C++-Kenntnisse sind allerdings sehr beschränkt. Kannst du das so mal ausprobieren?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#7

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 12:04
Okay.

Code:
class IBaseInterface: public IUnknown
{
    virtual __stdcall void* GetHandle() = 0;
};

extern "C" {
    ...
    IBaseInterface BaseCreateFileInfo(char* FileName, bool Extended);
}
Zitat:
Compiler: Default compiler
Building Makefile: "C:\Dokumente und Einstellungen\Lars\Desktop\BaseCTest\Makefile.win"
Führt make... aus
make.exe -f "C:\Dokumente und Einstellungen\Lars\Desktop\BaseCTest\Makefile.win" all
g++.exe -D__DEBUG__ -c main.cpp -o main.o -I"C:/Programme/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Programme/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Programme/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Programme/Dev-Cpp/include/c++/3.4.2" -I"C:/Programme/Dev-Cpp/include" -I"C:/Dokumente und Einstellungen/Lars/Desktop/BaseCTest" -pg -g3

In file included from main.cpp:2:
C:/Dokumente und Einstellungen/Lars/Desktop/BaseCTest/baseEngine.h:91: error: invalid return type for function `IBaseInterface BaseCreateFileInfo(char*, bool)'
C:/Dokumente und Einstellungen/Lars/Desktop/BaseCTest/baseEngine.h:91: error: because the following virtual functions are abstract:
C:/Programme/Dev-Cpp/include/unknwn.h:27: error: virtual HRESULT IUnknown::QueryInterface(const IID&, void**)
C:/Programme/Dev-Cpp/include/unknwn.h:28: error: virtual ULONG IUnknown::AddRef()
C:/Programme/Dev-Cpp/include/unknwn.h:29: error: virtual ULONG IUnknown::Release()
C:/Dokumente und Einstellungen/Lars/Desktop/BaseCTest/baseEngine.h:74: error: virtual void* IBaseInterface::GetHandle()

main.cpp: In function `int main(int, char**)':

main.cpp:15: error: cannot allocate an object of type `IBaseInterface'
main.cpp:15: error: since type `IBaseInterface' has abstract virtual functions
main.cpp:15: error: cannot allocate an object of type `IBaseInterface'
main.cpp:15: error: since type `IBaseInterface' has abstract virtual functions
main.cpp:15: error: cannot declare variable `Face' to be of type `IBaseInterface'
main.cpp:15: error: since type `IBaseInterface' has abstract virtual functions
Selbst wenn ich das class durch ein interface ersetze bleibt der fehler.
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Delphi's Interfaces in C++

  Alt 1. Jun 2009, 12:10
Du musst bedenken, dass Klassen in C++ standardmäßig auf dem Stack abgelegt werden. Grundsätzlich solltest du also überall IBaseInterface durch IBaseInterface* ersetzen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  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 17:33 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