So I figured that I’d talk about FTDI’s Linux D2XX drivers for a little bit, and about some odd things that they do.
First of all, FTDI makes really nice chips. We use them at work. The problem came about as follows: we tried to have both an SPI device and a normal serial port on an FTDI 4232H, since it has 4 possible serial ports. So, we figured that using the FTDI D2XX drivers would work, in conjunction with their MPSSE drivers to communicate with the SPI device.
As it turns out, FTDI tries to be clever with their drivers. That, or they have no idea how Linux works(I don’t know if this affects Windows as well.)
You see, what FTDI does is to dynamically load the methods that they are going to call.
That is not the right way to do it.
You know why?
Because that’s the job OF THE LINKER.
This is why when linking with D2XX drivers, you need to pass -ldl to the linker.
Also, this is done in the initializer of the drivers, which happens to be name my_init, presumably because they simply copied whatever example they found on the internet in order to do this. There are very few occasions where it is appropriate to use an initializer in a library. This is not one of them. You know why? Because their library is built on top of libusb. So there isn’t even anything special going on.
Now, FTDI’s MPSSE library also has an initializer named my_init. So you can’t statically link the libraries in. Dynamic linking links cleanly, but the program doesn’t work. And as it turns out, you just send MPSSE commands to the serial port once you put it into MPSSE mode. So libraries are being duplicated now.
So what can be done to fix this problem?
Well, it’s very simple.
You can link shared libraries to each other.
So, when creating libFTD2XX, FTDI should remove the initializer, and pass in -lusb to the linker. Sure, those of us who link to the library may also have to link to libusb, but it’s a small price to pay to be able to use the software properly. It also has the nice side effect of having a linking error when compiling, instead of a runtime segfault in the initializer which would happen with earlier versions of the library.