I am currently working on a Java application that uses JNA to access some FTDI libraries, both D2XX and LibFT4222. I have used JNAerator to create the JNA used. This is all working correctly on Windows platforms. However when trying to run the software on Mac I come into a problem with LibFT4222.
FT_OpenEx In D2XX appears to work correctly, resulting in no error code, I can also check its returned description to see it listed as “FT4222 A”. I am also able to perform other functions without returning an unexpected error code (such as closing it twice, the first time resulting in no error code, the second resulting in one as expected). However when trying any operation using LibFT4222 on the Handle created by D2XX such as FT4222_I2CMaster_Init, FT4222_GetVersion or FT4222_GetClock it produces error code 1000 FT4222_DEVICE_NOT_SUPPORTED.
I have tried playing around with the generated JNA code such as changing the FT HANDLE type from PointerByReference to IntByReference, and can get it working on Windows correctly as before but still nothing seems to get it working on Mac.
The same logic works correctly using modified versions of the Sample C files that FTDI provides (using the same LibFT4222.dylib), so I know it will work correctly on the Mac. And as mentioned, all of the above works with no issues on Windows.
Would anyone be able to provide any insight on the differences between Mac OSX and Windows that might cause this behaviour?
Edited to include code, Example Java code (In this case the description will be "FT4222 A", and OpenEx appears to work correctly) This works on Windows but on Mac FT4222_I2CMaster_Init returns 1000:
Memory memory = new Memory(16);
memory.setString(0, "FT4222 A");
PointerByReference handle = new PointerByReference();
Ftd2xxLibrary.FT_OpenEx(new PVOID(memory),
Ftd2xxLibrary.FT_OPEN_BY_DESCRIPTION, handle);
FT4222Library.FT_HANDLE ftHandle = new FT4222Library.FT_HANDLE(handle.getValue());
logger.warn("init" + FT4222Library.FT4222_I2CMaster_Init(ftHandle, (int) 100));
Where FT_OpenEx is (automatically generated by JNAerator) : /**
* Original signature : <code>FT_STATUS FT_OpenEx(PVOID, DWORD, FT_HANDLE*)</code><br>
* <i>native declaration : line 336</i>
*/
public static native NativeLong FT_OpenEx(Ftd2xxLibrary.PVOID pArg1, int Flags, PointerByReference pHandle);
Where FT4222_I2CMaster_Initis (automatically generated by JNAerator) :
/**
* FT4222 I2C Functions<br>
* Original signature : <code>FT4222_STATUS FT4222_I2CMaster_Init(FT_HANDLE, uint32)</code><br>
* <i>native declaration : line 338</i>
*/
public static native int FT4222_I2CMaster_Init(FT4222Library.FT_HANDLE ftHandle, int kbps);
Where FT_HANDLE is (automatically generated by JNAerator) :
public static class FT_HANDLE extends PointerType {
public FT_HANDLE(Pointer address) {
super(address);
}
public FT_HANDLE() {
super();
}
};
C Code working correctly on Mac (returning 0):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ftd2xx.h"
#include "libft4222.h"
static void init()
{
FT_HANDLE ftHandle = (FT_HANDLE)NULL;
FT_OpenEx("FT4222 A", FT_OPEN_BY_DESCRIPTION, &ftHandle);
printf("Init %d",FT4222_I2CMaster_Init(ftHandle,100));
}
Different results on different platforms are often a case of type mapping, but there's not an obvious difference here. I will point out a few inconsistencies that I see in the code, in the hopes that you can further troubleshoot using this information.
The library return type of
FT_OpenEx()
isFT_STATUS
, and the return type ofFT4222_I2CMaster_Init()
isFT4222_STATUS
, which is further documented as an extension ofFT_STATUS
... and in fact they use the same enum integer value basis but it's not clear how they are further defined. Logically one would expect the same data types for both, however in your mapping theFT_STATUS
is mapped toNativeLong
and theFT4222_STATUS
is mapped toint
.In the header file,
FT_STATUS
is typedef'd toULONG
based on the Windows API. This is 4 bytes on Windows, but might be 8 bytes on macOS, suggesting theNativeLong
mapping is probably correct. ButULONG
is not a standard type on macOS so I'm not sure what it should be... perhaps instrumenting the C code to get the size of that type would be useful. Also, given thenative
(Direct Mapping) declaration, I suspect the primitiveint
return type may be problematic.Possibly related, the
FT4222_STATUS
codes are simplyenum
type in C, so the width is not guaranteed by standard. It wouldn't surprise me if the return type forFT4222_STATUS
wasshort
on macOS.I'm not sure why the return type would make a difference (short of stack corruption) but it's one thing to start looking at.