Bonjour,

Je cherche a lire sur un peripherique usb HID avec la libhid sous linux (ubuntu 10.04).
http://libhid.alioth.debian.org/

Le peripherique est fonctionnel et les droits correctement configurés car j'y accede sans probleme avec un programme en C et un autre en Purebasic.

Le code fpc/lazarus utilisé :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 
 program project1;
 
  {$mode objfpc}{$H+}
 
  uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Classes,dynlibs,sysutils;
 
 
  {$R *.res}
 
  Type
 
  hid_return_t = (HID_RET_SUCCESS := 0,HID_RET_INVALID_PARAMETER,
     HID_RET_NOT_INITIALISED,HID_RET_ALREADY_INITIALISED,
     HID_RET_FAIL_FIND_BUSSES,HID_RET_FAIL_FIND_DEVICES,
     HID_RET_FAIL_OPEN_DEVICE,HID_RET_DEVICE_NOT_FOUND,
     HID_RET_DEVICE_NOT_OPENED,HID_RET_DEVICE_ALREADY_OPENED,
     HID_RET_FAIL_CLOSE_DEVICE,HID_RET_FAIL_CLAIM_IFACE,
     HID_RET_FAIL_DETACH_DRIVER,HID_RET_NOT_HID_DEVICE,
     HID_RET_HID_DESC_SHORT,HID_RET_REPORT_DESC_SHORT,
     HID_RET_REPORT_DESC_LONG,HID_RET_FAIL_ALLOC,
     HID_RET_OUT_OF_SPACE,HID_RET_FAIL_SET_REPORT,
     HID_RET_FAIL_GET_REPORT,HID_RET_FAIL_INT_READ,
     HID_RET_NOT_FOUND);
 
 
 
  THIDInterfaceMatcher = record
     vendor_id : word;
     product_id :word;
     matcher_fn : pointer;
     custom_data : pointer;
     custom_data_length :word;
  end;
  HIDInterfaceMatcher = THIDInterfaceMatcher;
  PHIDInterfaceMatcher = ^HIDInterfaceMatcher;
 
  THidInit=function : hid_return_t ;
  THidNewInterface=function : pointer;
  THidForceOpen=function (hidif:pointer; iface:longint; matcher:PHIDInterfaceMatcher; retries:word):hid_return_t;
 
  var
    Hlib:TLibHandle;
    HidInit:THidInit;
    HidNewInterface:THidNewInterface;
    HidForceOpen:THidForceOpen;
 
    NewIface:pointer;
    IMU:THIDInterfaceMatcher;
    PIMU:PHIDInterfaceMatcher;
  begin
 
 
  Hlib:=loadlibrary('libhid.so');
  if Hlib<>nilhandle then writeln('Chargement lib OK');
  HidInit := THidInit(GetProcAddress(Hlib, 'hid_init'));
  HidNewInterface := THidNewInterface(GetProcAddress(Hlib, 'hid_new_HIDInterface'));
  HidForceOpen := THidForceOpen(GetProcAddress(Hlib, 'hid_force_open'));
 
 
  If HidInit()=HID_RET_SUCCESS then writeln('Init OK');
  NewIface:=HidNewInterface();
 
  IMU.vendor_id:=$20FF;
  IMU.product_id:=$0100;
  IMU.matcher_fn:=nil;
  IMU.custom_data:=nil;
  IMU.custom_data_length:=0;
 
 
  HidForceOpen(NewIface,1,@PIMU,3);
  if HidForceOpen(NewIface,0,@IMU,3) = HID_RET_SUCCESS then writeln('Ouverture OK');
 
  end.
J'obtiens cette erreur

An unhandled exception occurred at $00E47C3E :
EAccessViolation : Access violation
$00E47C3E
$00E48EA6
$0804837F
a la ligne ==> HidForceOpen(NewIface,1,@PIMU,3);
Le probleme semble venir du pointer NewIface.
Si je declare un int64 au lieu d'un type pointer plus d'erreur mais l'interface n'est pas ouverte.

En C j'utilise ce code qui fonctionne sans souci :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
//gcc -Wall -W -L/usr/lib/ -lhid hid.c -o hid
#include <hid.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
 
unsigned char INDATA[100];
int i;
double x;
 
int main(void)
{
  HIDInterface* hid;
  hid_return ret;
  HIDInterfaceMatcher matcher = { 0x20ff, 0x0100, NULL, NULL, 0 };
 
 
ret = hid_init();
if (ret != HID_RET_SUCCESS) {
printf("Erreur Init HID \n");
return -1;
}
else
{
printf("Init HID OK\n");
}	
 
hid = hid_new_HIDInterface();
if (hid == 0) {
printf("Erreur ouverture Interface\n"); 
return -1; 
}
else
{
printf("ouverture Interface OK\n");  
}
 
ret = hid_force_open(hid, 1, &matcher, 3);
printf("%d\n",ret);
ret = hid_force_open(hid, 0, &matcher, 3);
 
if (ret == HID_RET_SUCCESS) {
printf("IMU Ouverte\n"); 
}
else
{
printf("Erreur Ouverture IMU\n");
return -1;
}
 
 
ret=hid_interrupt_read(hid,0x82,INDATA,15,0);
if (ret == HID_RET_SUCCESS) {
printf("Lecture IMU OK\n"); 
}
else
{
printf("Erreur Lecture IMU\n");
return -1;
}
 
 
x = ((INDATA[4]|(INDATA[5]<<8))-32768)*0.000183105469;
 
printf (" valeur ==> %f\n",x);
 
return 0;
}


et en Purebasic ceci
Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
ImportC "/usr/lib/libhid.so"
  hid_init()
  hid_cleanup()
  hid_new_HIDInterface()
  hid_force_open (HIDInterface, iface,HIDInterfaceMatcher,Retries)
  hid_interrupt_read(HIDinterface,Adr,buf,len,f)
  hid_close(HIDInterface)
EndImport
 
 
#HID_RET_SUCCESS =0	
#HID_RET_INVALID_PARAMETER 	=1
#HID_RET_NOT_INITIALISED 	=2
#HID_RET_ALREADY_INITIALISED=3 	
#HID_RET_FAIL_FIND_BUSSES 	=4
#HID_RET_FAIL_FIND_DEVICES 	=5
#HID_RET_FAIL_OPEN_DEVICE 	=6
#HID_RET_DEVICE_NOT_FOUND 	=7
#HID_RET_DEVICE_NOT_OPENED 	=8
#HID_RET_DEVICE_ALREADY_OPENED =9	
#HID_RET_FAIL_CLOSE_DEVICE =10
#HID_RET_FAIL_CLAIM_IFACE 	=11
#HID_RET_FAIL_DETACH_DRIVER 	=12
#HID_RET_NOT_HID_DEVICE 	=13
#HID_RET_HID_DESC_SHORT 	=14
#HID_RET_REPORT_DESC_SHORT 	=15
#HID_RET_REPORT_DESC_LONG 	=16
#HID_RET_FAIL_ALLOC 	=17
#HID_RET_OUT_OF_SPACE 	=18
#HID_RET_FAIL_SET_REPORT 	=19
#HID_RET_FAIL_GET_REPORT 	=20
#HID_RET_FAIL_INT_READ 	=21
#HID_RET_NOT_FOUND 	=22
#HID_RET_TIMEOUT 	=23
 
 
Structure THIDInterfaceMatcher
  vendor_id.u
  product_id.u
  custom_matcher.l
  custom_data.l
  lon.q
EndStructure
 
Dim Indata.c(20)
 
If hid_init()=#HID_RET_SUCCESS
 
  *h=hid_new_HIDInterface()
 
  If *h
    Hid_force_open(*h,1,@Matcher,3)
    If hid_force_open(*h,0,@Matcher,3)=#HID_RET_SUCCESS
      If hid_interrupt_read(*h,$82,@InData(),15,0)=#HID_RET_SUCCESS
        For X=0 To 14 
          Debug InData(X)
        Next x
      EndIf
    EndIf
  EndIf
EndIf

Ci j'utilise en fpc les mêmes types de variable qu' en purebasic j'ai droit a un :
Access violation
Avez vous une idée

Merci