Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-09

libusb header translation and OOP wrapper

19 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Johann Glaser

Hi!

Some time ago somebody asked about USB support. I've now finished the libusb 1.0 header translation and object-oriented wrapper.

Please find them at
https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0 including a few examples to demonstrate the usage.

I've updated http://wiki.lazarus.freepascal.org/Hardware_Access#libusb

I also tried to update my entry in
http://www.freepascal.org/contrib/contribs.html but got a username/password problem (despite using the same as for the Wiki above).

Bye
Hansi

Reply by email

Christo
to Johann Glaser
Johann Glaser wrote 8 lines
Hi! Some time ago somebody asked about USB support. I've now finished the libusb 1.0 header translation and object-oriented wrapper. Please find them at https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0 including a few examples to demonstrate the usage.

Hi Hansi,

I'm interested in testing your wrapper. Unfortunately I cannot clone the git link above, I get an error (fatal:
https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0/info/refs not found: did you run git update-server-info on the server?). I could only clone what appears to be the master branch using:

git clone https://github.com/hansiglaser/pas-libusb

Unfortunately the master branch appears to be 2 months old. Any idea how I can clone the libusb-1.0 branch? I'm new to using git so it may be something trivial I'm missing.

Regards,
Christo

Reply by email

Henry Vermaak
to Christo
Christo wrote
Unfortunately the master branch appears to be 2 months old. Any idea how I can clone the libusb-1.0 branch? I'm new to using git so it may be something trivial I'm missing.

Try to clone git://github.com/hansiglaser/pas-libusb.git

Then you can checkout the 1.0 branch.

Henry

Reply by email

Graeme Geldenhuys
to Christo: I'm interested in testing your wrapper. Unfortunately I cannot clone the git link above,…
Christo wrote
I'm interested in testing your wrapper. Unfortunately I cannot clone the git link above, I get an error (fatal: https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0/info/refs not

That was a web link, not the git url. If you followed that link with your web browser, you would have seen at the top a ZIP button which you can use to download the latest code of that branch in a zip archive. There are also two git clone URL's. One uses the HTTP protocol, and the other uses the faster GIT protocol.

git clone https://github.com/hansiglaser/pas-libusb.git

or

git clone git://github.com/hansiglaser/pas-libusb.git

then do...

cd pas-libusb
git checkout libusb-1.0

Unfortunately the master branch appears to be 2 months old.

You simply forgot to switch to the 'libusb-1.0' branch.

Regards,
- Graeme -

Reply by email

Johann Glaser
to Graeme Geldenhuys

Hi!

Graeme Geldenhuys wrote 29 lines
On 2012-09-24 14:39, Christo wrote: > I'm interested in testing your wrapper. Unfortunately I cannot clone > the git link above, I get an error (fatal: > https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0/info/refs not That was a web link, not the git url. If you followed that link with your web browser, you would have seen at the top a ZIP button which you can use to download the latest code of that branch in a zip archive. There are also two git clone URL's. One uses the HTTP protocol, and the other uses the faster GIT protocol. git clone https://github.com/hansiglaser/pas-libusb.git or git clone git://github.com/hansiglaser/pas-libusb.git then do... cd pas-libusb git checkout libusb-1.0 > Unfortunately the master branch appears to be 2 months old. You simply forgot to switch to the 'libusb-1.0' branch.

Thanks Graeme and Henry for taking this "support request". :-)

BTW: Another user asked whether I'll release the files under a modified LGPL Lazarus/FPC license. Yes, definitely. I hope I can push these changes during the weekend.

Bye
Hansi

Reply by email

Bernd
to Christo: I'm interested in testing your wrapper. Unfortunately I cannot clone the git link above,…

2012/9/24 Christo :

I'm new to using git so it may be something trivial I'm missing.

Regarding git,

I highly recommend using the easygit wrapper to make life easier, especially when you come from SVN because git will be very confusing in the beginning if you are used to svn and then try to understand the cryptic git commands. It has helped me a lot in the beginning (and still does) and it was the only thing that was finally able to convince me of the great usefulness of git:

https://github.com/blog/333-easy-git

Its just one huge perl script that you put into your path and then use eg instead of git and have a simpler and more logical command line syntax for most commonly used workflows. Unfortunately it is not actively maintained anymore and some commands do not work as expected with recent versions of git, for this there is a more recent fork here:

https://gitorious.org/~smarr/eg/smarrs-mainline/trees/master

Reply by email

Graeme Geldenhuys
to Bernd
Bernd wrote
I highly recommend using the easygit wrapper to make life easier, especially when you come from SVN because git will be very confusing

Thanks for the tip, but Git is *not* difficult to use. To cover the average developer workflow, you need like 3-4 commands max. If you can't remember 4 commands, then you have bigger issues than git.

If all else fails, then remember one of these:

git help
git help <command>

Git has excellent help with lots and lots of example commands to learn from, and ASCII art to help visualize what it does. If you still have problems, simply use 'git alias' and setup SVN-like commands for git. For example:

Used to using 'svn up'? No problems, do the same in git.

git up --> can maybe execute: git pull origin or
git co <url> --> can maybe execute: git clone <url>

There are some very handy aliases created by many. Use Google to find them.

Regards,
- Graeme -

Reply by email

Bernd
to Graeme Geldenhuys

2012/9/25 Graeme Geldenhuys :

Thanks for the tip, but Git is *not* difficult to use. To cover the average developer workflow, you need like 3-4 commands max. If you can't remember 4 commands, then you have bigger issues than git.

I know that git is not as complicated as it initially seems but by default it is doing its best to be as cryptic, strange behaving and unaccessible as possible. I almost believe Linus did this on purpose. It needed easygit to finally make me comfortable with git and see its advantages.

For example

svn commit

versus

git status
git stage whatever needs to be staged
git commit

or

git commit -a

versus

eg commit

eg commit is much more intelligent, it will immediately commit -a if it detects that there is nothing staged yet but it will warn and ask you when it detects unstaged changes and something else *is* already staged.

then there are subtle differences regarding which remote branches to pull from and push to by default, git has some totally unintuitive defaults and surprising behavior for many things while eg would just do the right thing[TM].

and btw the git help you mentioned is the worst help I have seen so far in the last 30 years. Try eg help to see how helpful help needs to look like.

Reply by email

Christo
to Johann Glaser: Hi! Some time ago somebody asked about USB support. I've now finished the libusb 1.0…
Johann Glaser wrote
Hi! Some time ago somebody asked about USB support. I've now finished the libusb 1.0 header translation and object-oriented wrapper.

Hi Hansi,

I see that the imported functions in libusb.pas are declared with the cdecl calling convention. According to the libusb header this is so for all operating systems except windows which is apparently compiled using the stdcall calling convention.

Any ideas on how to define the calling convention in the import unit so that it is either stdcall or cdecl depending on the target OS?

Regards,
Christo

Reply by email

Johann Glaser
to Christo

Hi!

Christo wrote 15 lines
On Sun, 2012-09-23 at 23:26 +0200, Johann Glaser wrote: > Hi! > > Some time ago somebody asked about USB support. I've now finished the > libusb 1.0 header translation and object-oriented wrapper. Hi Hansi, I see that the imported functions in libusb.pas are declared with the cdecl calling convention. According to the libusb header this is so for all operating systems except windows which is apparently compiled using the stdcall calling convention. Any ideas on how to define the calling convention in the import unit so that it is either stdcall or cdecl depending on the target OS?

Thanks for pointing this out.

I only have access to Linux and don't know anything about Windows development. So, I ask you (and anybody else) on the best and cleanest way to make libusb.pas working in Linux and other OS.

Thanks
Hansi

Reply by email

Henry Vermaak
to Christo: I see that the imported functions in libusb.pas are declared with the cdecl calling…
Christo wrote
Any ideas on how to define the calling convention in the import unit so that it is either stdcall or cdecl depending on the target OS?

I've used a macro for this in the past. E.g. :

{$macro on}
{$ifdef windows}
  {$define CCONV:=stdcall}
{$else}
  {$define CCONV:=cdecl}
{$endif}

Then use CCONV where you would specify the calling convention.

Henry

Reply by email

Sven Barth
to Henry Vermaak
Henry Vermaak wrote 14 lines
On 25 September 2012 20:57, Christo wrote: > Any ideas on how to define the calling convention in the import unit so > that it is either stdcall or cdecl depending on the target OS? I've used a macro for this in the past. E.g. : {$macro on} {$ifdef windows} {$define CCONV:=stdcall} {$else} {$define CCONV:=cdecl} {$endif} Then use CCONV where you would specify the calling convention.

I would use "extdecl" instead of "CCONV" as the IDE and fpdoc has special code to handle this (as they don't support macros).

Regards,
Sven

Reply by email

Christo
to Henry Vermaak: I've used a macro for this in the past. E.g. : {$macro on} {$ifdef windows} {$define…
Henry Vermaak wrote 12 lines
On 25 September 2012 20:57, Christo wrote: > Any ideas on how to define the calling convention in the import unit so > that it is either stdcall or cdecl depending on the target OS? I've used a macro for this in the past. E.g. : {$macro on} {$ifdef windows} {$define CCONV:=stdcall} {$else} {$define CCONV:=cdecl} {$endif}

Thanks Henry, that macro worked. I however have a problem statically linking to the libusbx library on Windows. I've downloaded the Windows libusbx 1.0.14 library from sourceforge and pointed the compiler to the mingw32 folder containing libusb-1.0.a.

It complains about undefined symbols such as:
project1.lpr(18,1) Error: Undefined symbol: LIBUSB_LIBUSB_INIT $PLIBUSB_CONTEXT$$LONGINT

I have changed the calling convention to cdecl and then it also
complains:  project1.lpr(18,1) Error: Undefined symbol: _libusb_init

I've managed to load the library dynamically using LoadLibrary and then loading each function/procedure using GetProcedureAddress. This works both on windows and on Linux.

Anyone knows why the static linking fails on Windows XP sp2? I'm using fpc 2.6.0 and have also tried the MS32 .lib library with no success.

Reply by email

Johann Glaser
to Sven Barth: I would use "extdecl" instead of "CCONV" as the IDE and fpdoc has special code to handle…

Hi!

Sven Barth wrote 18 lines
Am 25.09.2012 23:16, schrieb Henry Vermaak: > On 25 September 2012 20:57, Christo wrote: >> Any ideas on how to define the calling convention in the import unit so >> that it is either stdcall or cdecl depending on the target OS? > > I've used a macro for this in the past. E.g. : > > {$macro on} > {$ifdef windows} > {$define CCONV:=stdcall} > {$else} > {$define CCONV:=cdecl} > {$endif} > > Then use CCONV where you would specify the calling convention. I would use "extdecl" instead of "CCONV" as the IDE and fpdoc has special code to handle this (as they don't support macros).

Thank you for all your valuable suggestions!

I've now relicensed the units under the modified LGPL (as used by Lazarus) and the examples as public domain.

Additionally I've included the above macro (using "extdecl").

https://github.com/hansiglaser/pas-libusb/tree/libusb-1.0

I also updated my other Pascal translations for the GNU Readline library https://github.com/hansiglaser/pas-readline and the TCL interpreter https://github.com/hansiglaser/pas-tcl . Note that the GNU Readline library is pure GPL itself, therefore my stuff is GPL too.

Bye
Hansi

Reply by email

Christo
to Johann Glaser: Hi! Thanks for pointing this out. I only have access to Linux and don't know anything…
Johann Glaser wrote
I only have access to Linux and don't know anything about Windows development. So, I ask you (and anybody else) on the best and cleanest way to make libusb.pas working in Linux and other OS.

I have played around with your library to get it working on Windows XP. The most significant change I had to make was to change the libusbx import from static linking to dynamic loading. I just couldn't get the static linking working in windows.

This created a slight problem with requiring the cthreads unit because the libusbx library is multithreaded. I have added this to the libusb unit but it needs to be tested more because I don't understand how threading between C and fpc works.

Attached please find a diff file summarizing my changes based on your git copy from about a week ago.

Reply by email

Johann Glaser
to Christo

Hi!

Christo wrote 19 lines
On Tue, 2012-09-25 at 22:32 +0200, Johann Glaser wrote: > I only have access to Linux and don't know anything about Windows > development. So, I ask you (and anybody else) on the best and cleanest > way to make libusb.pas working in Linux and other OS. I have played around with your library to get it working on Windows XP. The most significant change I had to make was to change the libusbx import from static linking to dynamic loading. I just couldn't get the static linking working in windows. This created a slight problem with requiring the cthreads unit because the libusbx library is multithreaded. I have added this to the libusb unit but it needs to be tested more because I don't understand how threading between C and fpc works. Attached please find a diff file summarizing my changes based on your git copy from about a week ago.

Thanks for providing feedback and patches!

The major changes are that you use LoadLibrary instead of dynamic linking at program start. Note that $LINKLIB is really doing dynamic linking, not static linking. Therefore I don't see why procedural variables should be needed here.

Secondly you test whether libusb_get_port_number() and libusb_get_port_path() are available. I don't know how to handle this properly. Why not just update to 1.0.12?

Third, at some points you added the unit CThreads. Looking at the libusbx source code (and API documentation) reveals, that they don't use threading, they only use the mutexes (pthread_mutex_*) and condition variables (pthread_cond_*). I also don't know whether it is necessary to install the Pascal Thread Manager therefore. I'll start a dedicated thread for that.

Finally, you have added a different implementation of GetUSec which works on Windows. Thanks for that!

For the clarification of the CThreads and the LoadLibrary stuff I've created two separate branches libusb-1.0-cthreads and libusb-1.0-dynlib with your changes (with slight capitalization changes, ...). I'll merge these branches to libusb-1.0 as soon as these issues are clarified.

Thanks again
Hansi

Reply by email

Christo
to Johann Glaser
Johann Glaser wrote
The major changes are that you use LoadLibrary instead of dynamic linking at program start. Note that $LINKLIB is really doing dynamic linking, not static linking. Therefore I don't see why procedural variables should be needed here.

I actually didn't have to go the Loadlibrary route, you are right. I have changed the "external;" attribute to "external dllname;' and just specify dllname at the top of the unit - see attached diff.

Secondly you test whether libusb_get_port_number() and libusb_get_port_path() are available. I don't know how to handle this properly. Why not just update to 1.0.12?

I also can't think of a proper way to test. Perhaps just add a comment next to these function declarations in libusb.pas to remind users these functions may not be implemented in older libusbx versions?

Show quoted text 6 lines
Third, at some points you added the unit CThreads. Looking at the libusbx source code (and API documentation) reveals, that they don't use threading, they only use the mutexes (pthread_mutex_*) and condition variables (pthread_cond_*). I also don't know whether it is necessary to install the Pascal Thread Manager therefore. I'll start a dedicated thread for that.

After making several changes and upgrading to libusbx 1.0.14 I no longer require CThreads to run the test in Debian. I'm not sure why I needed it before.

Reply by email