Zo'n 1 byte array aan het eind van een struct wordt vaak gebruikt als placeholder, je kunt in een stuct de grootte van een array niet dynamisch maken (zo werkt C gewoon niet). In werkelijkheid is de data dan groter dan 1 byte maar een array pointer wijst altijd naar de eerst byte zodat je nog steeds een goede pointer hebt ookal klopt de grootte niet.

Op 29 december 2006 00:02:52 schreef free_electron:
dit is onleesbaar voor mij ( ik ken niet genoeg C. ik krijg hoofdpijn van die taal)


struct usb_interface {
  struct usb_interface_descriptor *altsetting;
  int num_altsetting;
};

Kleine tip, meestal zijn C types achterstevoren beter te lezen. ipv 'struct usb_interface_descriptor *altsetting' lees het als 'altsetting is een pointer (*) naar een usb_interface_descriptor struct'. De toevoeging 'struct' is trouwens echt iets uit C, in C++ hoeft dat niet meer en wordt het meestal weggelaten.

[Bericht gewijzigd door madwizard op ]

das inderdaad waar ik bang voor was ....
er wordt weer gebruik gemaakt van bizarre dingen (lees : vuiligheid) die gewoonweg niet te porteren vallen.

dit ding retourneert een soort 'linked list' ...

en dit is ook al helemaal onnozel :


struct usb_device {
  struct usb_device *next, *prev;
  char filename[LIBUSB_PATH_MAX];
  struct usb_bus *bus;
  struct usb_device_descriptor descriptor;
  struct usb_config_descriptor *config;
  void *dev;		/* Darwin support */
  unsigned char devnum;
  unsigned char num_children;
  struct usb_device **children;
};

struct usb_bus {
  struct usb_bus *next, *prev;
  char dirname[LIBUSB_PATH_MAX];
  struct usb_device *devices;
  unsigned long location;
  struct usb_device *root_dev;
};

dit begrijp ik niet :


struct usb_device {
  struct usb_device *next, *prev;

hoe kan een structuur nu een referentie naar zijn eigen bevatten ?

en hoe kan de ene struct een referentie naar een andere bevatten die dan weer naar de eerste wijst ...

das om onnozel van te worden...

dat placeholder mechanisme snap ik maar dat kan nooit 1 char zijn. elke pointer is een 32 bit getal..... dus dat kan niks anders dan een long zijn.

tis een miserieding tot en met. ik heb ook al de source van de dll proberen te bestuderen. daar staat nergens geen lijn commentaar in wat het doet , hoe het werkt ... tis triestig. ik dacht dat de bedoleing van copen source was dat iederen kon zien hoe het werkte. maar zoals het nu is kan je telkens het warmm water ( ik zou eerder durven spreken van 'water op kamertemperatuur' terug uitvinden.

ik begin er stillekesaan genoeg van te krijgen.

nog iets waar ik niet aan uit kan:


struct usb_device {
  struct usb_device *next, *prev;

  char filename[LIBUSB_PATH_MAX];

  struct usb_bus *bus;

  struct usb_device_descriptor descriptor;
  struct usb_config_descriptor *config;

waarom is de voorlaatste lijn geen pointer ?

[Bericht gewijzigd door free_electron op ]

Voor een beetje C programmeur is dit allemaal echt totaal geen probleem hoor. Als je VB gewend bent en nooit met C gewerkt hebt is het natuurlijk allemaal moeilijk maar dat wil nog niet zeggen dat het slecht of raar is.

Op 29 december 2006 02:55:24 schreef free_electron:
das inderdaad waar ik bang voor was ....
er wordt weer gebruik gemaakt van bizarre dingen (lees : vuiligheid) die gewoonweg niet te porteren vallen.

Je moet niet vergeten dat C een vrij low-level taal is. Datatypes hebben vaste groottes, omdat het nou eenmaal direct zo in het geheugen wordt gezet. Je kunt niet een array maken die de ene keer groter is dan de andere. Dit kan wel met een pointer (de pointer is dan altijd even groot) maar de usb descriptor heeft de tekst *direct* in de structure staan. Volgens mij zit het ook echt zo in de usb descriptor zelf, waarschijnlijk moet de structur daarom ook exact zo als in het USB config pakket zijn. De structure zou eigenlijk een variabele grootte moeten hebben, en dat kan gewoonweg niet in C. Dus moet je andere methodes verzinnen. Netter is een pointer gebruiken maar als dit inderdaad gebruikt wordt om de descriptor zelf echt te parsen moet het toch exact zo gedaan worden. Juist als je met hardware gaat werken krijg je vaak vreemde structures.

dit begrijp ik niet :


struct usb_device {
  struct usb_device *next, *prev;

hoe kan een structuur nu een referentie naar zijn eigen bevatten ?

Gewoon een pointer naar een structure van hetzelfde type, geen probleem toch? Ook gewoon een linked list (twee richtingen op).

en hoe kan de ene struct een referentie naar een andere bevatten die dan weer naar de eerste wijst ...

A heeft een pointer naar B, B heeft een pointer naar A. Geen probleem.

dat placeholder mechanisme snap ik maar dat kan nooit 1 char zijn. elke pointer is een 32 bit getal..... dus dat kan niks anders dan een long zijn.

Het is geen pointer, het is echt een losse char die in de structure zit (en eventuele andere chars volgen daar direct achter). Wel is het trouwens een short en geen char omdat het unicode is (verkeerd gelezen). De structure is dus 4 bytes, twee bytes voor de eerste velden en 2 bytes voor de eerste short ('karakter') van de string. De pointer krijg je pas als je die zelf maakt door aan de structure te refereren:

struct usb_string_descriptor desc = ...;
short *pDescriptor = &desc.wData

Nu is pDescriptor een pointer naar het wData veld. Via die pointer kun je ook de andere bytes lezen. desc.wData[3] oid kan je trouwens ook gebruiken, C controleert niet of je index out of bounds is (omdat de lengte van een array nou eenmaal niet opgeslagen wordt, het is low-level).

nog iets waar ik niet aan uit kan:


struct usb_device {
  struct usb_device *next, *prev;

  char filename[LIBUSB_PATH_MAX];

  struct usb_bus *bus;

  struct usb_device_descriptor descriptor;
  struct usb_config_descriptor *config;

waarom is de voorlaatste lijn geen pointer ?

Waarschijnlijk omdat er maar een device descriptor is staat die direct in de structure (in C kan dat, in veel andere talen wordt het altijd een pointer). Die is dan gewoon direct te bereiken via device.descriptor. Scheelt apart geheugen alloceren en opruimen. Zou me niets verbazen als die config pointer naar meerdere configurations kan wijzen, en dan moet je wel een pointer gebruiken.

Hoe maak je in VB een type declaratie ?

Dit is een stukje uit Delphi, hoe zet ik dat om in VB ?



type
  Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

  Tusb_device = Record
    next : pointer;
    prev : pointer;
    filename : array [0..511] of char;
    bus : pointer;
    config : pointer;
    dev : pointer;
    devnum : char;
    num_children : char;
    children : pointer;
  end;
  Pusb_device = ^Tusb_device;

  Tusb_bus = Record
    next : pointer;
    prev : pointer;
    dirname : array [0..511] of char;
    devices : pointer;
    location : longint;
    root_dev : pointer;
  end;
  Pusb_bus = ^Tusb_bus;

Hoi MMSoft,

Een type variabele maak je zo:

Type soort
x as byte
y as boolean
z as integer
end Type

Hier vind uitleg over pointers in vb:
http://www.codeproject.com/vbscript/how_to_do_pointers_in_visual_basic…

Ik hoop dat je er wat aan hebt

Vincent.

Op 29 december 2006 10:11:51 schreef madwizard:
Gewoon een pointer naar een structure van hetzelfde type, geen probleem toch? Ook gewoon een linked list (twee richtingen op).

dat wordt heel moeilijk om te porteren naar VB....

Het is geen pointer, het is echt een losse char die in de structure zit

ok nu begrijp ik dat. maar ik snap nog altijd niet waarom ze het de ene keer zus en de andere keer zo doen. schrijf dat uniform en hou het simpel.

het is verrekte meoilijk voor iemand die er niks vanaf weet om dat te doorgronden.

ok nu begrijp ik dat. maar ik snap nog altijd niet waarom ze het de ene keer zus en de andere keer zo doen. schrijf dat uniform en hou het simpel.

Zoals ik al zei denk ik dat ze het zo gedaan hebben om de structure zo te krijgen dat z'n byte representatie precies zo is als in een usb descriptor. Daar heb je een byte length, een byte descriptorType en daarna direct de string als een serie bytes. Stel dat je dat in je geheugen hebt staan dan kun je een pointer daarnaar maken met dat structure type, en vervolgens direct de velden op naam uitlezen.

Ik heb een tijdje terug de vertaling gemaakt van C naar delphi, dit is ook de code die mmsoft een aantal posts naar boven heeft staan.

In delphi is het, net als in VB, ook niet mogelijk om binnen een structure (record in delphi) een pointer naar een structure van hetzelfde type aan te maken. Vandaar de enigzins "dirty" oplossing, gewoon een untyped pointer. Voor de DLL maakt dat helemaal niets uit.
Er zijn vast wel dergelijke truucjes te bedenken voor VB dacht ik zo?

Om even een simpel voorbeeldje te geven in delphi:



  Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

  Tusb_device = Record
    next : pointer;
    prev : pointer;
    filename : array [0..511] of char;
    bus : pointer;
    descriptor : Tusb_device_descriptor;
    config : pointer;
    dev : pointer;// void *dev;		/* Darwin support */
    devnum : char;
    num_children : char;
    children : pointer;
  end;
  Pusb_device = ^Tusb_device;


  Tusb_bus = Record
    next : pointer;
    prev : pointer;
    dirname : array [0..511] of char;
    devices : pointer;
    location : longint;
    root_dev : pointer;
  end;
  Pusb_bus = ^Tusb_bus;

function usb_find_busses  : integer;  stdcall; external 'libusb0.dll';
function usb_find_devices : integer;  stdcall; external 'libusb0.dll';
function usb_get_busses   : Pusb_bus; stdcall; external 'libusb0.dll';
function usb_open (dev : Pusb_device): Pusb_dev_handle; stdcall; external 'libusb0.dll';


function TUSB_Device.OpenDevice(vendorID, productID : word): Pusb_dev_handle;
var
  bus : Pusb_bus;
  dev : Pusb_device;
  found : boolean;
  udev : Pusb_dev_handle;
begin
  found := false;
  usb_find_busses;
  usb_find_devices;
  bus := usb_get_busses;
  while bus <> NIL do
  begin
    dev := bus.devices;
    while dev <> NIL do
    begin
      if (dev.descriptor.idVendor = vendorID) and (dev.descriptor.idProduct = productID) then
      begin
        found := true;
        udev := usb_open(dev);
      end;
      dev := dev.next;
    end;
    bus := bus.next;
  end;
  if found then
    result := udev
  else
    result := NIL;
end;

Op 4 januari 2007 00:16:52 schreef KillerB the Supreme:
Ik heb een tijdje terug de vertaling gemaakt van C naar delphi, dit is ook de code die mmsoft een aantal posts naar boven heeft staan.

Er zijn vast wel dergelijke truucjes te bedenken voor VB dacht ik zo?

de vraag is dan : als je daar gewoon een pointer doorgeeft : waar staat de data dan ? ( met andere woorden : wordt er genoeg memory gealloceeerd om de boel te stockeren ? ) das immers de reden dat je een pointer naar een structuur doorgeeft : je zorgt daar dat er genoeg memory is om de boel te stockeren. gans die boel is een linked list die groeit en krimpt in functie van het aantal devices wat ingeplugd is.

het blijft een vreemde manier om dingen door te geven.
veel simpeler was geweest om al die miserie af te handelen IN de dll.

er is ook geen 'pointer' datatype in vb. je moet door middel van copymame en varptr de boel achterhalen en moven naar waar je wilt ( copymem is ene windows api call )

dit betekent dat er een klets glue code moet gemaakt worden in vb om die data te retrieven.

het is veel simpeler (denk ik) om in ene tussen dll een nieuwe API te definieren die de boel platklopt

api :

usb_init

usb_finddevices ( retourneert een integer die aangeeft hoeveel er gevonden zijn , bijvoorbeel 3 geeft aan dat er 4 devices zijn ( 0 tot en met 3 ))

usb_info(device nummer,datablock) device nummer zit dan tussen 0 en de waarde die je bekomen hebt uit usb_finddevices

usb_info (device nummer,datablock)
stockeert in 'datablock' een fixed size string met daarin comma delimited data (of desnoods fixed size velden) : gans die usb descriptor zit daar in.
als het device ondertussen unplugged is komt er een lege string terug.

usb_open(device ) opnieuw een nummer uit de lijst. . retourneert 0 of 1 ( 1=success ) ( 0 = failed )

en dan heb je gewoon send en receive. die je het device nummer, het aantal bytes en een pointer naar het datablok

usb_send(device_nummer,endpoint,aantalbytes,datablock)

usb_close(device)

tis properder en veel simpeler om te gebruiken , en het pint je niet vast op vuile 'c' constructies die niet porteerbaar zijn naar andere talen.

ik ben bang voor memory leak problems als die geneste lists niet proper kunnen gepasseerd worden.

nog een vraag :
wat betekent die ^ in de volgende code :


Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

[Bericht gewijzigd door free_electron op ]

Hoi free_electron,

^ = xor

voorbeeld:
main()
{
unsigned int a = 60; /* 60 = 0011 1100 */
unsigned int b = 13; /* 13 = 0000 1101 */
unsigned int c = 0;

c = a ^ b; /* 49 = 0011 0001 */
}
edit:dacht dat het c code was.

zie hier voor delphi:
http://delphi.about.com/od/beginners/l/aa011601a.htm

Vincent.

[Bericht gewijzigd door vinb op ]

Op 4 januari 2007 02:45:27 schreef free_electron:

de vraag is dan : als je daar gewoon een pointer doorgeeft : waar staat de data dan ? ( met andere woorden : wordt er genoeg memory gealloceeerd om de boel te stockeren ? ) das immers de reden dat je een pointer naar een structuur doorgeeft : je zorgt daar dat er genoeg memory is om de boel te stockeren. gans die boel is een linked list die groeit en krimpt in functie van het aantal devices wat ingeplugd is.

het blijft een vreemde manier om dingen door te geven.
veel simpeler was geweest om al die miserie af te handelen IN de dll.

Het wordt ook juist allemaal afgehandeld in de DLL. Dat is het hele idee erachter. De pointers verwijzen naar geheugen dat gealloceerd is in de DLL. Je hoeft zelf dus helemaal niets te alloceren, alleen de pointers naar de betreffende structures.

Op 4 januari 2007 02:45:27 schreef free_electron:

nog een vraag :
wat betekent die ^ in de volgende code :


Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

^ wil zeggen dat Pusb_dev_handle een pointer is naar een structure van het type Tusb_dev_handle. De eerste typedeclaratie van Tusb_dev_handle is wat verwarrend, het is eigenlijk een handle, ipv een pointer (maar dat komt op het zelfde neer, 4 bytes). Anders gezegd, Pusb_dev_handle is dus een pointer naar een devicehandle.

Delphi is best makkelijk in pointers, het symbool ^ "wijst" ergens heen, dit is sneller te begrijpen als de * van C. In C wordt de * ook gebruikt voor dereferencing, erg verwarrend. Delphi heeft daarvoor het @ symbool. Als je @ al vertaald naar "at" (en niet ape-staartje ;)) dan snap je direct dat er gedereferenced wordt.

Op 4 januari 2007 03:08:40 schreef vinb:
Hoi free_electron,

^ = xor

voorbeeld:
main()
{
unsigned int a = 60; /* 60 = 0011 1100 */
unsigned int b = 13; /* 13 = 0000 1101 */
unsigned int c = 0;

c = a ^ b; /* 49 = 0011 0001 */
}
edit:dacht dat het c code was.

zie hier voor delphi:
http://delphi.about.com/od/beginners/l/aa011601a.htm

Vincent.

Dat kan toch helemaal niet bij


Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

Op 4 januari 2007 12:29:47 schreef Henry S.:


Tusb_dev_handle = pointer;
  Pusb_dev_handle = ^Tusb_dev_handle;

Dat is Delphi code, niet C code. Daar komt de verwarring door. In C is het dakje een XOR operator en is dit geen geldige code.

Hoi Henry en jowi,

Jullie hebben gelijk,
daar kwam ik achter 5 min. nadat ik gepost had.

Vervolgens heb ik mijn bericht geedit zie tekst na edit:

Op 4 januari 2007 03:08:40 schreef vinb:

edit:dacht dat het c code was.

zie hier voor delphi:
http://delphi.about.com/od/beginners/l/aa011601a.htm

Vincent.

kzal vandaag nog ne keer ene poging wagen om het in VB te doen.

die dephi code is tenminste een stuk leesbaarder dan usb.h ...

kheb ondertussen bij Intel wat code gehaald in zuivere VB geschreven om ook USB te doen ZONDER externe DLL.
blijkt dat je dat kan via API calls naar windows zelf .....

oh zonder dll??? daar ben ik ook wel geinteresseerd in! gewoon standaard win-aapjes?

bon we zijn een stuk verder.
ik heb een paar support routines geschreven om in het memory te kunnen rondkoteren. zo kan ik 'kijken' wat er echt terugkeert en dat te mappen op mijn structuren.


Option Explicit
' twee woorden uitleg :
' shortint in C is een Integer in VB
' Char is een byte in VB
' pointers komen ALTIJD terug als long !
' functienamen in DLL's zijn CASE sensitive !! 
' de enige manier om dit te forceren is het gebruik van ALIAS in de
' functiedeclaratie. dit zorgt er voor dat niet accidenteel een naam 
' van case verandert door een user typo...
' VB strings zijn ALTIJD unicode !!! let daar geweldig mee op.

 Const LIBUSB_PATH_MAX = 512
 

'Device and/or Interface Class codes
    Const USB_CLASS_PER_INTERFACE = 0
    Const USB_CLASS_AUDIO = 1
    Const USB_CLASS_COMM = 2
    Const USB_CLASS_HID = 3
    Const USB_CLASS_PRINTER = 7
    Const USB_CLASS_MASS_STORAGE = 8
    Const USB_CLASS_HUB = 9
    Const USB_CLASS_DATA = 10
    Const USB_CLASS_VENDOR_SPEC = &HFF
'Descriptor types
    Const USB_DT_DEVICE = &H1
    Const USB_DT_CONFIG = &H2
    Const USB_DT_STRING = &H3
    Const USB_DT_INTERFACE = &H4
    Const USB_DT_ENDPOINT = &H5
    Const USB_DT_HID = &H21
    Const USB_DT_REPORT = &H22
    Const USB_DT_PHYSICAL = &H23
    Const USB_DT_HUB = &H29
'Descriptor sizes per descriptor type
    Const USB_DT_DEVICE_SIZE = 18
    Const USB_DT_CONFIG_SIZE = 9
    Const USB_DT_INTERFACE_SIZE = 9
    Const USB_DT_ENDPOINT_SIZE = 7
    Const USB_DT_ENDPOINT_AUDIO_SIZE = 9
    Const USB_DT_HUB_NONVAR_SIZE = 7
'Enpoint Descriptors...
    Const USB_MAXENDPOINTS = 32
    Const USB_ENDPOINT_ADDRESS_MASK = &HF
    Const USB_ENDPOINT_DIR_MASK = &H80
    Const USB_ENDPOINT_TYPE_MASK = &H3
    Const USB_ENDPOINT_TYPE_CONTROL = 0
    Const USB_ENDPOINT_TYPE_ISOCHRONOUS = 1
    Const USB_ENDPOINT_TYPE_BULK = 2
    Const USB_ENDPOINT_TYPE_INTERRUPT = 3
'Diverse
    Const USB_MAXINTERFACES = 32
    Const USB_MAXALTSETTING = 128
    Const USB_MAXCONFIG = 8
'Standard requests
    Const USB_REQ_GET_STATUS = &H0
    Const USB_REQ_CLEAR_FEATURE = &H1
    Const USB_REQ_SET_FEATURE = &H3
    Const USB_REQ_SET_ADDRESS = &H5
    Const USB_REQ_GET_DESCRIPTOR = &H6
    Const USB_REQ_SET_DESCRIPTOR = &H7
    Const USB_REQ_GET_CONFIGURATION = &H8
    Const USB_REQ_SET_CONFIGURATION = &H9
    Const USB_REQ_GET_INTERFACE = &HA
    Const USB_REQ_SET_INTERFACE = &HB
    Const USB_REQ_SYNCH_FRAME = &HC
    Const USB_TYPE_STANDARD = 0
    Const USB_TYPE_CLASS = &H20       ' (0x01 << 5)  waarschijnlijk shift left ...
    Const USB_TYPE_VENDOR = &H40      ' (0x02 << 5) dus ik heb de boel al geshift
    Const USB_TYPE_RESERVED = &H60     '(0x03 << 5) hier
    Const USB_RECIP_DEVICE = &H0
    Const USB_RECIP_INTERFACE = &H1
    Const USB_RECIP_ENDPOINT = &H2
    Const USB_RECIP_OTHER = &H3
   
    Const USB_ENDPOINT_IN = &H80
    Const USB_ENDPOINT_OUT = &H0
    Const USB_ERROR_BEGIN = 500000
' Data structures
Type USB_Descriptor_Header
     bLength As Byte
     bDescriptorType As Byte
End Type
Type USB_String_descriptor
     bLength As Byte
     bDescriptorType As Byte
     wdata As Integer          ' dit wordt gebruikt als plaeholder voor de array . is eigenlijk ene pointer
End Type
Type USB_Hid_Descriptor
     bLength As Byte
     bDescriptorType As Byte
     bcdHID As Integer
     bCountrycode As Byte
     bNumdescriptors As Byte
End Type
Type USB_Endpoint_Descriptor
     bLength As Byte
     bDescriptorType As Byte
     bEndpointaddress As Byte
     bmAttributes As Byte
     wMaxPacketSize As Integer
     bInterval As Byte
     bRefresh As Byte
     bSynchAddress As Byte
     extra As Byte              ' Dit is ene placeholder. is eigenlijk een pointer naar de data ararray
     extralen As Integer
End Type
Type USB_Interface_Descriptor
     bLength As Byte
     bDescriptorType As Byte
     bInterfaceNumber As Byte
     bAlternateSetting As Byte
     bNumEndpoints As Byte
     bInterfaceClass As Byte
     bInterfaceSubClass As Byte
     bInterfaceProtocol As Byte
     iInterface As Byte
     EndPoint As Long 'dit is ene pointer naar een type : USB_EndPoint_Descriptor
     extra As Byte
     extralen As Integer
End Type
Type USB_Interface
     AltSetting As Long 'dit is een pointer naar een type : USB_Interface_Descriptor
     Num_AltSetting As Integer
End Type
Type USB_Config_Descriptor
     bLength As Byte
     bDescriptorType As Byte
     wTotalLength As Integer
     bNumInterfaces As Byte
     bConfigurationValue As Byte
     iConfiguration As Byte
     bmAttributes As Byte
     MaxPower As Byte
     Interface As Long ' pointer naar een type : USB_Interface
     extra As Byte     ' pointer naar extra descriptors
     extralen As Long
End Type
Type USB_Device_Descriptor
     bLength As Byte
     bDescriptorType As Byte
     bcdUSB As Integer
     bDeviceClass As Byte
     bDeviceSubClass As Byte
     bDeviceProtocol As Byte
     bMaxPacketSize0 As Byte
     idVendor As Integer
     idProduct As Integer
     bcdDevice As Integer
     iManufacturer As Byte
     iProduct As Byte
     iSerialNumber As Byte
     bNumConfigurations As Byte
End Type
Type USB_Ctrl_Setup
  bRequestType As Byte
  bRequest As Byte
  wValue As Integer
  wIndex As Integer
  wLength As Integer
End Type
Type USB_Device
     next_dev As Long  ' pointer naar een type : USB_device
     prev_dev As Long  ' pointer naar een type : USB_device
     filename(LIBUSB_PATH_MAX) As Byte
     Bus As Long       ' pointer naar een type : USB_Bus
     Descriptor As USB_Device_Descriptor ' dit is een geforwarde struct :  USB_Device_Descriptor
     Config As USB_Config_Descriptor     ' dit is een geforwarde struct : USB_Config_Descriptor
     dummy As Long ' dummy pointer voor darwin support
     devnum As Byte
     num_children As Byte
     children As Long     ' dit is een pointer naar een array van types : usb_device . het aantal zit in 'num_children
End Type
Type USB_Bus
     next_dev As Long   ' pointers naar een zelfde type : usb_bus
     prev_dev As Long   ' pointers naar een zelfde type : usb_bus
     DirName(LIBUSB_PATH_MAX) As Byte
     Devices As Long ' pointer naar een type : USB_Device
     Location As Single
     root_device As Long ' pointer naar het root device type : usb_device
End Type
Type usb_dll
     major As Long
     minor As Long
     micro As Long
     nano As Long
End Type
Type usb_driver
     major As Long
     minor As Long
     micro As Long
     nano As Long
End Type
Type usb_version
     dll As usb_dll
     driver As usb_driver
End Type

Type USB_dev_handle
     pointer As Long ' dit is een pointer naar interne data in libusb.dll
End Type

' procedures
' opgelet ! de functinamen MOETEN lowercase zijn !!! ik heb aliassen gebruikt om de boel te forceren

Declare Sub USB_Init Lib "libusb0.dll" Alias "usb_init" ()
Declare Function USB_Find_Busses Lib "libusb0.dll" Alias "usb_find_busses" () As Integer
Declare Function USB_Find_Devices Lib "libusb0.dll" Alias "usb_find_devices" () As Integer
Declare Function USB_get_busses Lib "libusb0.dll" Alias "usb_get_busses" () As Long ' dit geeft een pointer naar USB_Bus
Declare Function USB_open Lib "libusb0.dll" Alias "usb_open" _
        (ByRef Device As USB_Device) As Long ' pointer naar een USB_dev_handle
Declare Function USB_close Lib "libusb0.dll" Alias "usb_close" _
        (ByRef Device As USB_dev_handle) As Integer
Declare Function USB_set_configuration Lib "libusb0.dll" Alias "usb_set_configuration" _
        (ByRef Device As USB_dev_handle, _
         ByVal Configuration As Integer) As Integer
Declare Function USB_set_altinterface Lib "libusb0.dll" Alias "usb_set_altinterface" _
        (ByRef Device As USB_dev_handle, _
         ByVal Alternate As Integer) As Integer
Declare Function USB_resetep Lib "libusb0.dll" Alias "usb_resetep" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Long) As Integer
Declare Function USB_clear_Halt Lib "libusb0.dll" Alias "usb_clear_Halt" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Long) As Integer
Declare Function USB_reset Lib "libusb0.dll" Alias "usb_reset" _
        (ByRef Device As USB_dev_handle) As Integer
Declare Function USB_Claim_Interface Lib "libusb0.dll" Alias "usb_claim_interface" _
        (ByRef Device As USB_dev_handle, _
         ByVal Interface As Integer) As Integer
Declare Function USB_release_Interface Lib "libusb0.dll" Alias "usb_release_Interface" _
        (ByRef Device As USB_dev_handle, _
         ByVal Interface As Integer) As Integer
Declare Function USB_control_Msg Lib "libusb0.dll" Alias "usb_control_msg" _
        (ByRef Device As USB_dev_handle, _
         ByVal RequestType As Integer, _
         ByVal Request As Integer, _
         ByVal Value As Integer, _
         ByVal Index As Integer, _
         ByRef Bytes As String, _
         ByVal Size As Integer, _
         ByVal TimeOut As Integer) As Integer
Declare Function USB_get_string Lib "libusb0.dll" Alias "usb_get_string" _
        (ByRef Device As USB_dev_handle, _
         ByVal Index As Integer, _
         ByVal LangId As Integer, _
         ByRef Buf As String, _
         ByVal BufLen As Long) As Integer
Declare Function USB_get_string_simple Lib "libusb0.dll" Alias "usb_get_string_simple" _
        (ByRef Device As USB_dev_handle, _
         ByVal Index As Integer, _
         ByRef Buf As String, _
         ByVal BufLen As Long) As Integer
Declare Function USB_get_descriptor Lib "libusb0.dll" Alias "usb_get_descriptor" _
        (ByRef Device As USB_dev_handle, _
         ByVal sType As String, _
         ByVal Index As String, _
         ByRef Buf, _
         ByVal Size As Integer) As Integer
Declare Function USB_get_descriptor_by_endPoint Lib "libusb0.dll" Alias "usb_get_descriptor_by_endPoint" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Integer, _
         ByVal sType As String, _
         ByVal Index As String, _
         ByRef Buf, _
         ByVal Size As Integer) As Integer
Declare Function USB_Bulk_Write Lib "libusb0.dll" Alias "usb_bulk_write" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Integer, _
         ByRef Bytes As String, _
         ByVal Size As Integer, _
         ByVal TimeOut As Integer) As Integer
Declare Function USB_Bulk_Read Lib "libusb0.dll" Alias "usb_bulk_read" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Integer, _
         ByRef Bytes As Byte, _
         ByVal Size As Integer, _
         ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Write Lib "libusb0.dll" Alias "usb_interrupt_write" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Integer, _
         ByRef Bytes As Byte, _
         ByVal Size As Integer, _
         ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Read Lib "libusb0.dll" Alias "usb_interrupt_read" _
        (ByRef Device As USB_dev_handle, _
         ByVal EndPoint As Integer, _
         ByRef Bytes As Byte, _
         ByVal Size As Integer, _
         ByVal TimeOut As Integer) As Integer

'-----------------------------------------------------------------------------------------------
' Hieronder staan routines die mij toestaan in het geheugen rond te 'koteren'
' Dump is een routine die memory dumpt . kwestie van te zien wat er werkelijk terugkeert ...
' copymemeory is een kernel call die mij toestaat om vanaf een gegeven address ( de pointer )
' een klets geheugen te kopieren naar ergenst anders

' bijvoorbeeld ik krijg ene pointer terug naar een of andere structuur die 10 byte lang is
' ik maak iets gelijkaardig in visual basic aan.
'  laat ons zeggen x is de geretrouneerde pointer
'  type my_type
'     a1 as long ' 4 byte
'     a2 as long ' 4 byte
'     a3 as integer ' 2 byte
'  end type
'  dim y as my_type
'  copymemory(y,x,10)  ' kopieer 10 bytes vanaf pointer 'x' naar 'y'
'                      ' aangezien variableen altijd via pointer toorgegeven worden in vb gebeurt dit.
'                        de structuur wordt dus mooi overgekopieerd
'                        en ik kan gewoon a2 opvragen .... dat geeft mij dan byte 4 tot en met 7 uit de 10 byte array

Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
        (pTo As Any, _
         uFrom As Any, _
         ByVal lSize As Long)

' dump is een routine die memory dumpt . kwestie van te zien wat er werkelijk terugkeert ...
Public Function Dump(ByVal Buffer As Long, ByVal Block_Size As Long) As String
   Dim Internal_Buffer() As Byte ' make internal storage space
   Dim Internal_Block_Size
   Dim Result As String          ' this holds the 'dump' in user readable form
   Dim i As Long, j As Long
   ReDim Internal_Buffer(0 To Block_Size - 1) As Byte
   Call CopyMemory(Internal_Buffer(0), ByVal Buffer, Block_Size)
   Result = String(81, "=") & vbCrLf & "Buffer Address = 0x" & Hex$(Buffer) & _
            " : Block_Size = 0x" & Hex$(Block_Size) & " (" & Block_Size & ")d"
   If Block_Size Mod 16 = 0 Then    ' boundary needs to be correct
      Internal_Block_Size = Block_Size
   Else
      Internal_Block_Size = ((Block_Size \ 16) + 1) * 16
   End If
   For i = 0 To (Internal_Block_Size - 1)
      If (i Mod 16) = 0 Then Result = Result & vbCrLf & Right$("00000000" & Hex$(Buffer + i), 8) _
                                      & "  " & Right$("0000" & Hex$(i), 4) & "  "
      If i < Block_Size Then
         Result = Result & Right$("0" & Hex(Internal_Buffer(i)), 2)
      Else
         Result = Result & "  "
      End If
      If (i Mod 16) = 15 Then
         Result = Result & "  "
         For j = (i - 15) To i
            If j < Block_Size Then
               If Internal_Buffer(j) >= 32 And Internal_Buffer(j) <= 126 Then
                  Result = Result & Chr$(Internal_Buffer(j))
               Else
                  Result = Result & "."
               End If
            End If
         Next j
         ElseIf (i Mod 8) = 7 Then ' Insert '-'
            Result = Result & "-"
      Else ' Insert space
         Result = Result & " "
      End If
   Next i
   Dump = Result & vbCrLf & String(81, "=") & vbCrLf
End Function
Public Function PointerToStringA(ByVal lpStringA As Long) As String
   Dim Buffer() As Byte
   Dim nLen As Long
   If lpStringA Then
      nLen = lstrlenA(ByVal lpStringA)
      If nLen Then
         ReDim Buffer(0 To (nLen - 1)) As Byte
         CopyMemory Buffer(0), ByVal lpStringA, nLen
         PointerToStringA = StrConv(Buffer, vbUnicode)
      End If
   End If
End Function

Public Function PointerToStringW(ByVal lpStringW As Long) As String
   Dim Buffer() As Byte
   Dim nLen As Long
   If lpStringW Then
      nLen = lstrlenW(lpStringW) * 2
      If nLen Then
         ReDim Buffer(0 To (nLen - 1)) As Byte
         CopyMemory Buffer(0), ByVal lpStringW, nLen
         PointerToStringW = Buffer
      End If
   End If
End Function
Public Function PointerToDWord(ByVal lpDWord As Long) As Long
   Dim nRet As Long
   If lpDWord Then
      CopyMemory nRet, ByVal lpDWord, 4
      PointerToDWord = nRet
   End If
End Function

maak een formpje aan met 4 command buttons
(command1 tot en met command4) en een label ( dat label noem je usrmsg


Private Sub Command1_Click()
    USB_Init
End Sub
Private Sub Command2_Click()
    Dim x As Long
    x = USB_Find_Busses()
    msg "USB_find_busses returned : " & x
End Sub
Private Sub Command3_Click()
    Dim x As Long
    x = USB_Find_Devices()
    msg "USB_find_devices returned : " & x
End Sub
Private Sub Command4_Click()
    Dim x As Long
    Dim my_usb_bus As USB_Bus   ' maak een variabele aan van het type usb_bus
    x = USB_get_busses()        ' x bevat nu een pointer naar een array van type USB_Bus
    msg "pointer returned " & x ' toon het addresss
    Debug.Print Dump(x, &H2FF)  ' kijk eens wat er in zit ....
End Sub
Sub msg(txt$)
    usrmsg.Caption = txt$
End Sub
Private Sub Command5_Click()
   usb_get_devices
End Sub
Private Sub Form_Load()
    usrmsg.Width = Me.Width
End Sub

dat staat je to om al de bus te proben en het aantal devices te retrieven.

nu de rest nog ...

der moet wat 'glue' code gemaakt worden om door middel van copymemory de boel te kunnen 'afwandelen'.

das voor de komende uren... eerst eten :p

Op 4 januari 2007 00:16:52 schreef KillerB the Supreme:
Ik heb een tijdje terug de vertaling gemaakt van C naar In delphi is het, net als in VB, ook niet mogelijk om binnen een structure (record in delphi) een pointer naar een structure van hetzelfde type aan te maken.

Jawel hoor, dat gaat prima met een forward type declaration...

Op 4 januari 2007 22:14:22 schreef picsels:
[...]
Jawel hoor, dat gaat prima met een forward type declaration...

hmmmm doe es een voorbeeldje?

inderdaad . doe eens een voorbeeldje in VB ?
het kan niet bij mijn weten

Op 4 januari 2007 22:24:50 schreef KillerB the Supreme:
[...]hmmmm doe es een voorbeeldje?

Aldus (in Delphi... ik ben been VB-man want ik ken al Delphi...):


  Pusb_device = ^Tusb_device;
  Tusb_device = Record
    next : Pusb_device;
    prev : Pusb_device;
    // ...
  end;

Hmm tja het werkt inderdaad :) Waarom ik dat niet eerder heb geprobeerd weet ik niet...

@free_electron: lekker bezig, met VB hehe. Je moet lol hebben op een bepaalde manier.....
Waarom deze vertaling naar VB, omdat het de bedoeling is om het multi language te maken?
Waarom VB.... viese taal

[edit] trouwens die next en prev pointer kunnen ook een void pointer zijn. Die kan je later weer typecaste (als dat kan in vb) naar het goeie type.

[Bericht gewijzigd door Captnoord op ]

Op 4 januari 2007 23:26:47 schreef KillerB the Supreme:
Hmm tja het werkt inderdaad :) Waarom ik dat niet eerder heb geprobeerd weet ik niet...

Misschien ben ik te oud.
Dit kon al met Turbo Pascal V3.0 (jaja, begin jaren 80) :+