/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
Interface med C++ DLL...
Fra : Thomas Eg Jørgensen


Dato : 14-02-07 12:24

Hej,

Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en er
en wrapper for nogle low-level bluetooth funktioner. Mit problem er at
en af de vigtige funktioner returnere en object af en "ukendt" klasse.
Eller dvs at jeg har definitionen af klassen i C++, men hvordan får jeg
den ind i Delphi?

Lidt simplificeret så har jeg følgende stående i dokumentationen:
int _stdcall InitBMDll(char* dllName)
CInquiry* _stdcall GetCInquiry()
int _stdcall CleanBMDll()

Dette har jeg så omsat til delphi:
function InitLibrary(dllName: pchar): integer; stdcall; external
'BM_Dll.dll' name 'InitBMDll';

function GetCInquiry: pointer; stdcall; external 'BM_Dll.dll';
function CleanBMDll: integer; stdcall; external 'BM_Dll.dll';

Både initializeringen og "oprydningen" fungere fint (der findes
yderligere nogle funktioner i DLL'en som jeg kan bruge til tests, så jeg
ved det virker)...

MEN, hvordan hulen skal jeg kunne bruge den pointer jeg får tilbage fra
GetCInquiry?

Jeg har klassedefinitionen i C, men det kan vel ikke rigtigt hjælpe mig,
kan det? Den er rimlig stor, men kommer her alligevel:
**********Klippet direkte fra dokumentationen**********
// Device inquiry & pairing
class BARAMAN3_API CInquiry
{
public:
static CInquiry* GetInstance();

// Pairing related functions
typedef enum {
SUCCESS,
ALREADY_BONDED,
BAD_PARAMETER,
FAIL
} BOND_RETURN_CODE;

virtual BOND_RETURN_CODE Bond(BD_ADDR bda, LPTSTR pin_code) const;
virtual BOOL BondQuery(BD_ADDR bda) const;
virtual BOOL UnBond(BD_ADDR bda) const;

// Is device ready
virtual BOOL GetLocalDevice(BD_ADDR bda = NULL) const;

// Device discovery
virtual BOOL StartFindDevices(const BOOL flush = TRUE, const DEV_CLASS
devClass = DummyClass);
virtual void StopFindDevices();
virtual int GetInquiryCount() const;
virtual int GetNext(const int ind, BD_NAME name, BD_ADDR bda, DEV_CLASS
cl) const;

typedef enum {
SPP,
HST,
A2DP,
DUN,
} SERVICE_TYPE;

// Service discovery
virtual BOOL StartDiscoverServices(BD_ADDR adr, SERVICE_TYPE type);
virtual int GetSppServicesInfo(const BD_ADDR BdAddr, UINT8 &scn, TCHAR*
serviceName);

// Parent window registration
virtual void RegisterWindow(const HWND hwnd);
// Autoconnect
virtual void SetAutoConnectManager(CAutoConnect* pManager);

// SPP GUID
static const GUID guid_SERVCLASS_SERIAL_PORT;
// HST GUID
static const GUID guid_SERVCLASS_HEADSET;
// DUN GUID
static const GUID guid_SERVCLASS_DIALUP_NETWORKING;
// A2DP GUID
static const GUID guid_SERVCLASS_A2DP;

#ifdef _COMONE_PLATFORM
// Baracoda internal use
virtual void SetDelegate(BaracodaPtrType ptr) { m_Delegate = ptr; }
virtual void SetPINDelegate(PINPtrType ptr) { m_PINDelegate = ptr; }
virtual void SetDeviceFoundDelegate(PINPtrType ptr) { m_DFDelegate =
ptr; }
#endif

private:
// Singleton
CInquiry();
CInquiry(const CInquiry&);
CInquiry& operator= (const CInquiry&);
~CInquiry();
static CInquiry* instance;

void OnDeviceResponded(const BD_ADDR bda, const DEV_CLASS devClass,
const BD_NAME bdName, const BOOL bConnected);
void OnInquiryComplete(const BOOL success, const short num_responses);
void OnDiscoveryComplete();

BOOL SetLinkTimeout(BD_ADDR bda, UINT8 tmo);

GUID m_pServiceGuid;
HWND m_RemoteHwnd;
CAutoConnect* m_pManager;

#ifdef BARAMAN3_API
friend BARAMAN3_API int _stdcall BMUnRegister();
#endif

friend class CBlueIf;
friend class CBtDevice;
CBlueIf* m_BtIf;

int m_NumDevices;
CBdInfo* m_pDevInfo[MAX_SERVER_DEVICES];

#ifdef _COMONE_PLATFORM
friend void GAP_Event_Handler(unsigned long msgType, void* msg);
BaracodaDelegate m_Delegate;
PINDelegate m_PINDelegate;
PINPtrType m_DFDelegate;
#endif
};
********Slut på klip********

Når det er almindelige typer der skal konverteres(int, strings osv) så
plejer jeg at kunne få tingene til at passe. Men med klasser bliver det
pludselig en anden sag, jeg kan slet ikke gennemskue hvordan jeg på
nogen måde kan få alt ovenstående til at passe...hvis bare en ting er
forkert "vil hele læsset jo vælte", ik?

Hvordan bør jeg gribe dette an?

Alle former for input, tanker, etc. er yderst velkommen da jeg er på
helt bar bund her

På forhånd tak....

MVH
Thomas


 
 
nic@aub.dk (14-02-2007)
Kommentar
Fra : nic@aub.dk


Dato : 14-02-07 14:18

On 14 Feb., 12:24, Thomas Eg Jørgensen <tho...@hest.notaplan.com>
wrote:
> Hej,
>
> Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en er
> en wrapper for nogle low-level bluetooth funktioner. Mit problem er at
> en af de vigtige funktioner returnere en object af en "ukendt" klasse.
> Eller dvs at jeg har definitionen af klassen i C++, men hvordan får jeg
> den ind i Delphi?

Jeg kan prøve

> static CInquiry* GetInstance();

Her skal du nok ha fat i en C++ ekspert Mere end mig ihvertfald.
Jeg vil TRO at du ikke behøver denne metode i din klasse.

> // Pairing related functions
> typedef enum {
> SUCCESS,
> ALREADY_BONDED,
> BAD_PARAMETER,
> FAIL
> } BOND_RETURN_CODE;

Denne her skal du dele op i Delphi
en type-erklæring af
TBondReturnCode=(brcSuccess, brcAlreadyBonded, brcBadParameter,
brcFail);
og så en
BondReturnCode: TBondReturnCode;
i din klasse.

> virtual BOND_RETURN_CODE Bond(BD_ADDR bda, LPTSTR pin_code) const;
> virtual BOOL BondQuery(BD_ADDR bda) const;
> virtual BOOL UnBond(BD_ADDR bda) const;

Virtuelle metoder vil ligge lige inden det sted pointeren peger på. At
undlade dem vil ikke ødelægge dine data, men vil give noget memory
leak hvis ikke .dll'en frigiver hukommelse fra dem (dvs hvis du
frigiver dit objekt vha .dll'en kan disse undværes, ellers kan du lave
tre andre virtuelle procedurer i din klasse for at hukommelsen går op)

*snip*

> typedef enum {
> SPP,
> HST,
> A2DP,
> DUN,
> } SERVICE_TYPE;

Samme som tidligere, split den op og erklær enumereringen som en type,
og en variabel af denne type i din klasse.

*snip*

> // SPP GUID
> static const GUID guid_SERVCLASS_SERIAL_PORT;
> // HST GUID
> static const GUID guid_SERVCLASS_HEADSET;
> // DUN GUID
> static const GUID guid_SERVCLASS_DIALUP_NETWORKING;
> // A2DP GUID
> static const GUID guid_SERVCLASS_A2DP;

Bare variable. Aner ikke hvordan du oversætter GUID til Delphi :)

> #ifdef _COMONE_PLATFORM
> // Baracoda internal use
> virtual void SetDelegate(BaracodaPtrType ptr) { m_Delegate = ptr; }
> virtual void SetPINDelegate(PINPtrType ptr) { m_PINDelegate = ptr; }
> virtual void SetDeviceFoundDelegate(PINPtrType ptr) { m_DFDelegate =
> ptr; }
> #endif

Du kan gøre det samme i Delphi med {$IFDEF} eller du kan finde ud af
hvorvidt denne define findes eller ej, og så evt udelade det.

> private:
> // Singleton
> CInquiry();
constructor Create();

> CInquiry(const CInquiry&);
constructor Create(CInquiry);
Copy constructor.

> CInquiry& operator= (const CInquiry&);
function _And(CInquiry): CInquiry;

> ~CInquiry();
destructor Free();

> static CInquiry* instance;
instance: CInquiry;
En klasse i Delphi betyder automatisk pointer. Hvis den ikke kan se
klassen inde i den selv (kan jeg ikke huske på stående fod) kan du
erstatte det med
instance: Pointer;

> void OnDeviceResponded(const BD_ADDR bda, const DEV_CLASS devClass,
> const BD_NAME bdName, const BOOL bConnected);
> void OnInquiryComplete(const BOOL success, const short num_responses);
> void OnDiscoveryComplete();
>
> BOOL SetLinkTimeout(BD_ADDR bda, UINT8 tmo);

Statiske metoder. Dem kan du helt undlade selvom du nok for brug for
at lave dem

> GUID m_pServiceGuid;
> HWND m_RemoteHwnd;
> CAutoConnect* m_pManager;

Simple variable igen - HWND oversættes normalt til THandle.

> #ifdef BARAMAN3_API
> friend BARAMAN3_API int _stdcall BMUnRegister();
> #endif

"friend" findes ikke i Delphi men bare lav den public.

> CBdInfo* m_pDevInfo[MAX_SERVER_DEVICES];

Så vidt jeg husker er dette et array af pointers - ikke en pointer til
et array. Men tjek lige op på det.

> Når det er almindelige typer der skal konverteres(int, strings osv) så
> plejer jeg at kunne få tingene til at passe. Men med klasser bliver det
> pludselig en anden sag, jeg kan slet ikke gennemskue hvordan jeg på
> nogen måde kan få alt ovenstående til at passe...hvis bare en ting er
> forkert "vil hele læsset jo vælte", ik?

Well, alle data vil blive lidt forskudt og du vil få nogle memory
leaks ;) Hvis du læser værdierne ud i en watch (og vel og mærke har en
test opsætning som gør at du ved hvad de BØR være) kan du som regel
finde disse fejl ret nemt.

Jeg håber det kan hjælpe dig igang


Thomas Eg Jørgensen (14-02-2007)
Kommentar
Fra : Thomas Eg Jørgensen


Dato : 14-02-07 17:12


<nic@aub.dk> skrev i en meddelelse
news:1171459058.201469.234810@v45g2000cwv.googlegroups.com...
>> Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en
>> er
>> en wrapper for nogle low-level bluetooth funktioner. Mit problem er
>> at
>> en af de vigtige funktioner returnere en object af en "ukendt"
>> klasse.
>> Eller dvs at jeg har definitionen af klassen i C++, men hvordan får
>> jeg
>> den ind i Delphi?
>
>> static CInquiry* GetInstance();
>
>Her skal du nok ha fat i en C++ ekspert Mere end mig ihvertfald.
>Jeg vil TRO at du ikke behøver denne metode i din klasse.
>

Der er så her min kæde hopper lidt af. Jeg er ikke meget inde i hvordan
hukommelsen styres på det her område, men jeg troede faktisk at klasse
definitionerne skulle være HELT ens, bit for bit, for ikke tingene
fungere? Hvordan vil de forskellige metoder ellers "vide" hvor den
ekserkverbare kode ligger(frem for f.eks. pointere til data)?

Min pointe er at der må være forskel på om jeg skriver
Tsomething = class
MineData: pchar;
function MinMetode:boolean;
end;
og
Tsomething = class
function MinMetode:boolean;
MineData: pchar;
end;

(bortset fra at compileren nok vil brokke sig over sidstnævnte!)

Problemet er vel så, at definitionen i C står i en anden rækkefølge end
i delphi og ergo kommer data'ene i en anden rækkefølge i hukommelsen?
Det er nok mig der misforstår de bagvedliggende processor i forbindelse
med compilering og ekserkveringen...men....ja....please enlighten me


>>[*snip*]
Tak


>> virtual BOND_RETURN_CODE Bond(BD_ADDR bda, LPTSTR pin_code) const;
>> virtual BOOL BondQuery(BD_ADDR bda) const;
>> virtual BOOL UnBond(BD_ADDR bda) const;
>
>Virtuelle metoder vil ligge lige inden det sted pointeren peger på. At
>undlade dem vil ikke ødelægge dine data, men vil give noget memory
>leak hvis ikke .dll'en frigiver hukommelse fra dem (dvs hvis du
>frigiver dit objekt vha .dll'en kan disse undværes, ellers kan du lave
>tre andre virtuelle procedurer i din klasse for at hukommelsen går op)

Hmm, jeg så et sted[1] at disse kunne omskrives til:
function BondQuery([something]): Boolean; virtual; cdecl; abstract;


>>[*snip*]
mere tak


>> void OnDeviceResponded(const BD_ADDR bda, const DEV_CLASS devClass,
>> const BD_NAME bdName, const BOOL bConnected);
>> void OnInquiryComplete(const BOOL success, const short
>> num_responses);
>> void OnDiscoveryComplete();
>>
>> BOOL SetLinkTimeout(BD_ADDR bda, UINT8 tmo);
>
>Statiske metoder. Dem kan du helt undlade selvom du nok for brug for
>at lave dem

Disse er så ikke virtuelle, det skal de ifølge [1] være for at jeg kan
bruge ovenstående stunt med abstrakte metoder?


>>[*snip*]
endnu mere tak


>> Når det er almindelige typer der skal konverteres(int, strings osv)
>> så
>> plejer jeg at kunne få tingene til at passe. Men med klasser bliver
>> det
>> pludselig en anden sag, jeg kan slet ikke gennemskue hvordan jeg på
>> nogen måde kan få alt ovenstående til at passe...hvis bare en ting er
>> forkert "vil hele læsset jo vælte", ik?
>
>Well, alle data vil blive lidt forskudt og du vil få nogle memory
>leaks ;) Hvis du læser værdierne ud i en watch (og vel og mærke har en
>test opsætning som gør at du ved hvad de BØR være) kan du som regel
>finde disse fejl ret nemt.

Hmmm, ja....jeg ved faktisk ikke rigtigt hvad de bør være:-/ Det er lidt
et sats:-/


>Jeg håber det kan hjælpe dig igang
Det kan det helt bestemt, tak for hjælpen

MVH
Thomas

[1]=http://www.rvelthuis.de/articles/articles-cppobjs.html


Mogens Hansen (14-02-2007)
Kommentar
Fra : Mogens Hansen


Dato : 14-02-07 23:01

>
><nic@aub.dk> wrote in message
>news:1171459058.201469.234810@v45g2000cwv.googlegroups.com...

[8<8<8<]
>> virtual BOND_RETURN_CODE Bond(BD_ADDR bda, LPTSTR pin_code) const;
>> virtual BOOL BondQuery(BD_ADDR bda) const;
>> virtual BOOL UnBond(BD_ADDR bda) const;
>
>Virtuelle metoder vil ligge lige inden det sted pointeren peger på.

Nej.
Virtuelle objekter ligger i kode-segmentet og objektet ligger i
data-segmentet.
Typisk har objekter med virtuelle metoder et ekstra "hemmeligt" datamedlem,
som er en pointer til den virtuelle funktions tabel.

Men det er sådan set ligegyldigt - for der er ingen dokumenteret måde at
sikre at en Delphi Language klasse er binær kompatibel med en C++ klasse.


> At
>undlade dem vil ikke ødelægge dine data, men vil give noget memory
>leak hvis ikke .

Nej - det hænger ikke sammen sådan.

>dll'en frigiver hukommelse fra dem (dvs hvis du
>frigiver dit objekt vha .dll'en kan disse undværes, ellers kan du lave
>tre andre virtuelle procedurer i din klasse for at hukommelsen går op)
>
>*snip*
>
>> typedef enum {
>> SPP,
>> HST,
>> A2DP,
>> DUN,
>> } SERVICE_TYPE;
>
>Samme som tidligere, split den op og erklær enumereringen som en type,
>og en variabel af denne type i din klasse.
>
>*snip*
>
>> // SPP GUID
>> static const GUID guid_SERVCLASS_SERIAL_PORT;
>> // HST GUID
>> static const GUID guid_SERVCLASS_HEADSET;
>> // DUN GUID
>> static const GUID guid_SERVCLASS_DIALUP_NETWORKING;
>> // A2DP GUID
>> static const GUID guid_SERVCLASS_A2DP;
>
>Bare variable. Aner ikke hvordan du oversætter GUID til Delphi :)

Nej - det går simpelt hen galt.


Venlig hilsen

Mogens Hansen



Mogens Hansen (14-02-2007)
Kommentar
Fra : Mogens Hansen


Dato : 14-02-07 22:37


"Thomas Eg Jørgensen" <thomas@hest.notaplan.com> wrote in message
news:45d2f162$0$90276$14726298@news.sunsite.dk...
> Hej,
>
> Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en er en
> wrapper for nogle low-level bluetooth funktioner. Mit problem er at en af
> de vigtige funktioner returnere en object af en "ukendt" klasse. Eller dvs
> at jeg har definitionen af klassen i C++, men hvordan får jeg den ind i
> Delphi?

Der er en god og en dårlig nyhed:
Den dårlige er at du har et forholdsvis komplekst problem.
Den gode er at den forholdsvis simpelt kan løses med noget "slave-arbejde".

Den dårlige nyhed:
Det vigtige at erkende er at DLL snitfladen kun giver direkte understøttelse
for C funktioner og simple parameter typer - svarende til hvad man finder i
Windows API'et.
Der er ikke noget standardiseret C++ DLL interface (ABI - application binary
interface). Det betyder at et C++ DLL generelt kun er kompatibelt med den
compiler det er lavet med.
Konkret kan man ikke generelt bruge et C++ DLL oversat med Borland
C++Builder fra en applikation oversat med Microsoft Visual C++, eller et C++
DLL oversat med Microsoft Visual C++ V6.0 fra en applikation oversat med
Microsoft Visual C++.NET 2005.

Den gode nyhed:
Man kan altid selv lave et wrapper DLL med en kompatibel C++ compiler, der
eksporterer nogle C funktioner svarende til C++ interface.
Dette DLL kan så kaldes fra Delphi, og man kan lave en Delphi klasse med et
interface svarende til C++ klassen, så det igen bliver nemt at kalde C++
klassen fra Delphi applikationen.

>
> Lidt simplificeret så har jeg følgende stående i dokumentationen:
> int _stdcall InitBMDll(char* dllName)
> CInquiry* _stdcall GetCInquiry()

I C wrapper DLL kan man lave en tilsvarende funktion, der blot returnerer en
typeløs pointer (bemærk jeg har ikke oversat den kode jeg skriver her):
typedef void* InquiryHandle;
InquiryHandle _stdcall GetCInquiry();


[8<8<8<]
> class BARAMAN3_API CInquiry
> {
> public:
> static CInquiry* GetInstance();

Enhver "static" member funktion, kan laves om til en C funktion:

extern "C"
{
InquiryHandle _stdcall CInquiry_GetInstance()
{
try {
return CInquiry::GetInstance();
}
catch(..) { // or more detailed error handling
return 0;
}
}
}

[8<8<8<]
> virtual BOOL BondQuery(BD_ADDR bda) const;
Enhver ikke static member-funktion kan laves om til en C funktion hvor
første argument er en pointer til objektet:
extern "C"
{
BOOL _stdcall CInquiry_BondQuery(const InquiryHandle inq, BD_ADDR dba)
{
try {
return reinterpret_cast<const CInquiry*>(inq)->BondQuery(dba);
}
catch(...) { // or more detailed error handling
return FALSE; // or something else for error indication
}
}
}

Efterhånden som funktions parametrene bliver mere komplicerede, skal der
tilsvarende mere avanceret håndtering af dem (marshalling).

> Alle former for input, tanker, etc. er yderst velkommen da jeg er på helt
> bar bund her

Du kan også lave en COM baseret wrapper med en kompatibel C++ compiler.
Det er væsentligt sværere at skrive og installere, men til gengæld er det
måske nemmere at bruge fra Delphi.

Du kan naturligvis også vælge at skrive applikationen med en kompatibel
C++ - men det er sikkert ikke en reel mulighed.

Venlig hilsen

Mogens Hansen



Brian Andersen \(www~ (15-02-2007)
Kommentar
Fra : Brian Andersen \(www~


Dato : 15-02-07 12:20

(kom til at sende denne meddelse privat - sorry!)

Hejsa,

tjek lige om det er et COM objekt du har fra C++. Det vil jeg formode det
er?! I så fald, så har du ingen problemer.

Prøv at aktivere menuen Project->Import Type Libarary. Se om du kan
importere .dll filen. Hvis ikke, så må du have fat i en C++ compiler og se
om du derfra selv kan skrive en wrapper???


-------------------------------------

Jeg kan se, at jeg ikke har fået læst det hele igennem før jeg fik svaret...


/Brian

"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:45d3810a$0$179$157c6196@dreader1.cybercity.dk...
>
> "Thomas Eg Jørgensen" <thomas@hest.notaplan.com> wrote in message
> news:45d2f162$0$90276$14726298@news.sunsite.dk...
>> Hej,
>>
>> Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en er en
>> wrapper for nogle low-level bluetooth funktioner. Mit problem er at en af
>> de vigtige funktioner returnere en object af en "ukendt" klasse. Eller
>> dvs at jeg har definitionen af klassen i C++, men hvordan får jeg den ind
>> i Delphi?
>
> Der er en god og en dårlig nyhed:
> Den dårlige er at du har et forholdsvis komplekst problem.
> Den gode er at den forholdsvis simpelt kan løses med noget
> "slave-arbejde".
>
> Den dårlige nyhed:
> Det vigtige at erkende er at DLL snitfladen kun giver direkte
> understøttelse for C funktioner og simple parameter typer - svarende til
> hvad man finder i Windows API'et.
> Der er ikke noget standardiseret C++ DLL interface (ABI - application
> binary interface). Det betyder at et C++ DLL generelt kun er kompatibelt
> med den compiler det er lavet med.
> Konkret kan man ikke generelt bruge et C++ DLL oversat med Borland
> C++Builder fra en applikation oversat med Microsoft Visual C++, eller et
> C++ DLL oversat med Microsoft Visual C++ V6.0 fra en applikation oversat
> med Microsoft Visual C++.NET 2005.
>
> Den gode nyhed:
> Man kan altid selv lave et wrapper DLL med en kompatibel C++ compiler, der
> eksporterer nogle C funktioner svarende til C++ interface.
> Dette DLL kan så kaldes fra Delphi, og man kan lave en Delphi klasse med
> et interface svarende til C++ klassen, så det igen bliver nemt at kalde
> C++ klassen fra Delphi applikationen.
>
>>
>> Lidt simplificeret så har jeg følgende stående i dokumentationen:
>> int _stdcall InitBMDll(char* dllName)
>> CInquiry* _stdcall GetCInquiry()
>
> I C wrapper DLL kan man lave en tilsvarende funktion, der blot returnerer
> en typeløs pointer (bemærk jeg har ikke oversat den kode jeg skriver her):
> typedef void* InquiryHandle;
> InquiryHandle _stdcall GetCInquiry();
>
>
> [8<8<8<]
>> class BARAMAN3_API CInquiry
>> {
>> public:
>> static CInquiry* GetInstance();
>
> Enhver "static" member funktion, kan laves om til en C funktion:
>
> extern "C"
> {
> InquiryHandle _stdcall CInquiry_GetInstance()
> {
> try {
> return CInquiry::GetInstance();
> }
> catch(..) { // or more detailed error handling
> return 0;
> }
> }
> }
>
> [8<8<8<]
>> virtual BOOL BondQuery(BD_ADDR bda) const;
> Enhver ikke static member-funktion kan laves om til en C funktion hvor
> første argument er en pointer til objektet:
> extern "C"
> {
> BOOL _stdcall CInquiry_BondQuery(const InquiryHandle inq, BD_ADDR dba)
> {
> try {
> return reinterpret_cast<const CInquiry*>(inq)->BondQuery(dba);
> }
> catch(...) { // or more detailed error handling
> return FALSE; // or something else for error indication
> }
> }
> }
>
> Efterhånden som funktions parametrene bliver mere komplicerede, skal der
> tilsvarende mere avanceret håndtering af dem (marshalling).
>
>> Alle former for input, tanker, etc. er yderst velkommen da jeg er på helt
>> bar bund her
>
> Du kan også lave en COM baseret wrapper med en kompatibel C++ compiler.
> Det er væsentligt sværere at skrive og installere, men til gengæld er det
> måske nemmere at bruge fra Delphi.
>
> Du kan naturligvis også vælge at skrive applikationen med en kompatibel
> C++ - men det er sikkert ikke en reel mulighed.
>
> Venlig hilsen
>
> Mogens Hansen
>



Thomas Eg Jørgensen (15-02-2007)
Kommentar
Fra : Thomas Eg Jørgensen


Dato : 15-02-07 13:35

"Brian Andersen (www.europeansoftwarehouse.com)" <x@x.x> skrev i en
meddelelse news:yjXAh.18$7F2.5@news.get2net.dk...
> tjek lige om det er et COM objekt du har fra C++. Det vil jeg formode
> det
> er?! I så fald, så har du ingen problemer.
>
> Prøv at aktivere menuen Project->Import Type Libarary. Se om du kan
> importere .dll filen. Hvis ikke, så må du have fat i en C++ compiler
> og se
> om du derfra selv kan skrive en wrapper???
>

Det var også det første jeg prøvede, men desværre, nej

Ellers tak for ideen...

MVH
Thomas


Mogens Hansen (15-02-2007)
Kommentar
Fra : Mogens Hansen


Dato : 15-02-07 14:23


"Brian Andersen (www.europeansoftwarehouse.com)" <x@x.x> wrote in message
news:yjXAh.18$7F2.5@news.get2net.dk...
> (kom til at sende denne meddelse privat - sorry!)

Det er hvad der sker

>
> Hejsa,
>
> tjek lige om det er et COM objekt du har fra C++. Det vil jeg formode det
> er?!

Man kan se at det ikke er et COM objekt, idet:
* der er en "static" funktion. Det findes ikke i COM interfaces
* der er datamedlemmer. Det findes ikke i COM interfaces
* der er friend erklæringer. Det findes ikke i COM interfaces
* der er private sektion. Det findes ikke i COM interfaces
* Metoderne returnerer ikke HRESULT. Det gør de i COM
* Klassen arver ikke fra IUnknown. Det skal de i COM

Venlig hilsen

Mogens Hansen



Brian Andersen \(www~ (15-02-2007)
Kommentar
Fra : Brian Andersen \(www~


Dato : 15-02-07 15:27

>>
>> Hejsa,
>>
>> tjek lige om det er et COM objekt du har fra C++. Det vil jeg formode det
>> er?!
>
> Man kan se at det ikke er et COM objekt, idet:
> * der er en "static" funktion. Det findes ikke i COM interfaces
> * der er datamedlemmer. Det findes ikke i COM interfaces
> * der er friend erklæringer. Det findes ikke i COM interfaces
> * der er private sektion. Det findes ikke i COM interfaces
> * Metoderne returnerer ikke HRESULT. Det gør de i COM
> * Klassen arver ikke fra IUnknown. Det skal de i COM


Jeps. Det har jeg spottet (o; Jeg fik næsten trykket på send knappen før jeg
fik svaret *s*. Jeg har korrigeret mig selv efter de stiplede linjer...

/Brian



Thomas Eg Jørgensen (15-02-2007)
Kommentar
Fra : Thomas Eg Jørgensen


Dato : 15-02-07 13:44

"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:45d3810a$0$179$157c6196@dreader1.cybercity.dk...
>> Jeg har en DLL som jeg gerne vil anvende nogle funktioner i. DLL'en
>> er en wrapper for nogle low-level bluetooth funktioner. Mit problem
>> er at en af de vigtige funktioner returnere en object af en "ukendt"
>> klasse. Eller dvs at jeg har definitionen af klassen i C++, men
>> hvordan får jeg den ind i Delphi?
>
> Der er en god og en dårlig nyhed:
> Den dårlige er at du har et forholdsvis komplekst problem.
> Den gode er at den forholdsvis simpelt kan løses med noget
> "slave-arbejde".
>
> Den dårlige nyhed:
> Det vigtige at erkende er at DLL snitfladen kun giver direkte
> understøttelse for C funktioner og simple parameter typer - svarende
> til hvad man finder i Windows API'et.
> Der er ikke noget standardiseret C++ DLL interface (ABI - application
> binary interface). Det betyder at et C++ DLL generelt kun er
> kompatibelt med den compiler det er lavet med.
> Konkret kan man ikke generelt bruge et C++ DLL oversat med Borland
> C++Builder fra en applikation oversat med Microsoft Visual C++, eller
> et C++ DLL oversat med Microsoft Visual C++ V6.0 fra en applikation
> oversat med Microsoft Visual C++.NET 2005.
>
> Den gode nyhed:
> Man kan altid selv lave et wrapper DLL med en kompatibel C++ compiler,
> der eksporterer nogle C funktioner svarende til C++ interface.
> Dette DLL kan så kaldes fra Delphi, og man kan lave en Delphi klasse
> med et interface svarende til C++ klassen, så det igen bliver nemt at
> kalde C++ klassen fra Delphi applikationen.
>

Hmm, ja...tænkte det nok...nå...men hul i det...så blev jeg da i det
mindste bekræftet i at jeg synes det var en svær opgave

>[*snip*]

Tak for tips'ene, jeg vil forsøge at lave en wrapper til DLL'en...

Tak...

MVH
Thomas


Mogens Hansen (16-02-2007)
Kommentar
Fra : Mogens Hansen


Dato : 16-02-07 07:09


"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:45d3810a$0$179$157c6196@dreader1.cybercity.dk...


> [8<8<8<]
>> virtual BOOL BondQuery(BD_ADDR bda) const;
> Enhver ikke static member-funktion kan laves om til en C funktion hvor
> første argument er en pointer til objektet:
> extern "C"
> {
> BOOL _stdcall CInquiry_BondQuery(const InquiryHandle inq, BD_ADDR dba)
> {
> try {
> return reinterpret_cast<const CInquiry*>(inq)->BondQuery(dba);
> }
> catch(...) { // or more detailed error handling
> return FALSE; // or something else for error indication
> }
> }
> }

Jeg kom til at tænke på at, givet at CInquiry er en singleton, så vil kald
formodentlig typisk se sådan ud
CInquiry::GetInstance()->BondQuery(dba);
(som er unødvendigt kompliceret, men buzz-word compliant: objekt orienteret
og bruger design patterns)
kan man skrive wrapper funktionen uden brug af objektet:

extern "C"
{
BOOL _stdcall CInquiry_Bond(BD_ADDR dba)
{
try {
return CInquiry::GetInstance()->BondQuery(dba);
}
catch(..) { // or more detailed error handling
return FALSE;
}
}
}

Så måske har du slet ikke brug for typen "InquiryHandle".

Bemærk dette er ikke en generel teknik - det jeg tidligere beskrev er
generelt.

Venlig hilsen

Mogens Hansen



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste