C++ - DLL aufruf umsetzen ->PureBasic

Für allgemeine Fragen zur Programmierung mit PureBasic.
PBuser
Beiträge: 12
Registriert: 03.10.2005 14:31

C++ - DLL aufruf umsetzen ->PureBasic

Beitrag von PBuser »

Hallo zusammen

ich habe eine C++ DLL. Aus dieser DLL soll ein USB-Device ausgelesen werden.
Hier der Aufruf laut Doku
prCAPI PR_GetDeviceList(prUInt32* pBufferSize, prDeviceList* pDeviceList);

Folgende Struktur ist gegeben:

#define prANY 1
typedef unsigned short prUInt16;
typedef unsigned long prUInt32;
typedef unsigned short prWChar;
#define MY_BUFFER_SIZE 20480L /* 20KB */


typedef struct{
prWChar DeviceInternalName[512] ;/* Internal devicve name (512 characters) */
prWChar ModelName[32]; /* Camera model name (32 characters) */
prUInt16 Generation; /* Camera generation number */
prUInt32 Reserved1; /* Reserved */
prUInt32 ModelID; /* Camera model ID */
prUInt16 Reserved2; /* Reserved */
prPorttype PortType; /* Port type 0x01
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Deine Strukturen sind IMHO inkorrekt. Fixe Strings würden nur im
Unicode-Modus funktionieren. Port ist nirgends als word definiert, also long.
Evtl. so:

Code: Alles auswählen

Structure prDeviceInfoTable
  DeviceInternalName.w[512]
  ModelName.w[32]
  Generation.w
  Reserved1.w
  ModelID.l
  Reserved2.w
  PortType.l
  Reserved3.l
EndStructure

Structure prDeviceList
  NumList.l
  DeviceInfo.prDeviceInfoTable[0]
EndStructure
Strings mit peek und poke nutzen (Unicode)
Für DeviceInfo.prDeviceInfoTable[0] ist Speicher zu allokieren
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
PBuser
Beiträge: 12
Registriert: 03.10.2005 14:31

Beitrag von PBuser »

Hallo ts-soft.
Vielen Dank für Deine Antwort.

Was heist Speicher allokiern?

Machen das diese C-Aufrufen?

Das habe ich nicht richtig verstanden!

BufferSize = MY_BUFFER_SIZE;
memset(Buffer, 0, MY_BUFFER_SIZE); <--20KB werden auf 0 gesetzt ?

Was wird hier eigentlich übergeben?
Ich dachte die Struktur?

err = PR_GetDeviceList(&BufferSize, (prDeviceList *)Buffer);


memset(DeviceListBuffer, 0, MY_BUFFER_SIZE); <- wird auf 0 gesetzt?
memcpy(DeviceListBuffer, Buffer, BufferSize); <- wird was kopiert ?


Danke
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

So ähnlich könnte es funktionieren:

Code: Alles auswählen

Structure prDeviceInfoTable
  DeviceInternalName.w[512]
  ModelName.w[32]
  Generation.w
  Reserved1.w
  ModelID.l
  Reserved2.w
  PortType.l
  Reserved3.l
EndStructure

Structure prDeviceList
  NumList.l
  *DeviceInfo.prDeviceInfoTable[0]
EndStructure

Prototype PR_GetDeviceList(*pBufferSize, *pDeviceList)

Define.l lib = OpenLibrary(#PB_Any, "C++.dll")
Define.prDeviceList test
Define.l Mem, I

If lib
  GetDeviceList.PR_GetDeviceList = GetFunction(Lib, "PR_GetDeviceList")
  Mem = AllocateMemory(2048)
  If Mem
    GetDeviceList(Mem, @test)
    
    For I = 0 To test\NumList
      Debug PeekS(test\DeviceInfo[I]\ModelName[0], 32, #PB_Unicode)
    Next
  EndIf
EndIf
Aber ohne DLL kann ichs nicht testen, c++ mag ich auch nicht :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
PBuser
Beiträge: 12
Registriert: 03.10.2005 14:31

Beitrag von PBuser »

Hallo ts-soft
Das mit dem Speicher allokieren und mit Peek zuzugreifen war eine gute Idee.
Habe jetzt den Return-Wert des DLL-Aufruf in einen allokieren Speicher geladen und diesen mit Peek ausgelesen.
(Die Strukturen sind oben beschreiben)
Programm sieht jetzt wie folgt aus:

Code: Alles auswählen

EnableExplicit
Prototype.l Proto_GetDeviceList(*Size.l, *mem.s) 
Define lib
Define s$
lib = OpenLibrary(#PB_Any,"C++.dll")
Global GetDeviceList.Proto_GetDeviceList = GetFunction(Lib, "PR_GetDeviceList") 
Define Size.l
Define r
Define Buffer.s
Define.l Mem, I, *pMem
Define c.c
buffer = Space(20480)
Mem = AllocateMemory(20480)
If mem
  *pMem = mem
EndIf
size = 20480
r = GetDeviceList(@Size,*pmem)
For i = 1 To size
  c = PeekC(*pmem)
  Debug(Str(i)+": " + Chr(c))
  *pmem+1  
Next
Die Ausgabe sieht wie folgt aus:
(Habe alles in eine zeile und die einzelnen zeichen in <> gesetzt)

<1><0><0><0>{<0>6<0>B<0>D<0>D<0>1<0>F<0>C<0>6<0>-<0>8<0>1<0>0<0>F<0>-<0>1<0>1<0>D<0>0<0>-<0>B<0>E<0>C<0>7<0>-<0>0<0>8<0>0<0>0<0>2<0>B<0>E<0>2<0>0<0>9<0>2<0>F<0>}<0>\<0>0<0>0<0>0<0>9<0><0><0><0><0><0><0><0><0>

Warum ist hinter jedem Zeichen ein Null-Wert?
Ist dies eine C++-Besonderheit? UniCode? Aus der Dokumentation der dll geht nichts hervor.

Hat jemand eine Idee?

Danke

code-tags gesetzt, ts-soft
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> Warum ist hinter jedem Zeichen ein Null-Wert?
Ist doch logisch, sind ja WCHAR (Unicode), also mit

Code: Alles auswählen

PeekS(*MEM, #PB_Any, #PB_Unicode)
auslesen

Würdest Du bitte Code Tags setzen, sieht ja schrecklich aus, wenn Du Code postes :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
PBuser
Beiträge: 12
Registriert: 03.10.2005 14:31

Beitrag von PBuser »

Danke für deine Antwort.

Hatte das Code-Tag nicht gesehen. :oops:
Antworten