I have a DLL with interface
struct modeegPackage
{
uint8_t version; // = 2
uint8_t count; // packet counter. Increases by 1 each packet
uint16_t data[6]; // 10-bit sample (= 0 - 1023) in big endian (Motorola) format
uint8_t switches; // State of PD5 to PD2, in bits 3 to 0
};
__declspec(dllexport) void __cdecl initSerial();
__declspec(dllexport) void __cdecl closeSerialPort();
__declspec(dllexport) struct modeegPackage __cdecl getPackage();
And C# adapter
class EEGCommunication
{
[StructLayout(LayoutKind.Sequential)]
public struct modeegPackage
{
/// unsigned char
public byte version;
/// unsigned char
public byte count;
/// unsigned int[6]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.U2)]
public UInt16[] data;
/// unsigned char
public byte switches;
}
private const string DLL = "libneureader-lib.dll";
[DllImport(DLL, EntryPoint = "_Z10initSerialv")]
public static extern void InitSerial();
[DllImport(DLL, EntryPoint = "_Z15closeSerialPortv")]
internal static extern void CloseSerialPort();
[DllImport(DLL, EntryPoint = "_Z10getPackagev", CallingConvention = CallingConvention.Cdecl)]
public static extern modeegPackage GetPackage();
}
But when I’m trying to call GetPackage method, I receive an error Method's type signature is not PInvoke compatible.
What’s wrong with my code?
UPDATE: Code updated
It is the array that is causing the problem. The pinvoke marshaller doesn’t like dealing with it in the specific case of returning a structure by value as a function return value. It is in general troublesome, the way this is done is highly compiler dependent. With good odds that you’ll have trouble since it sounds like you are using GCC. It is typically done by the caller allocating space for the return value on the stack and passing a pointer to it.
A crude but effective trick is to expand the array yourself, practical enough since it has only 6 elements. Substitute the array like this:
Which will solve the exception. Whether you’ll get the data correctly remains to be seen, if not then you may have to switch to MSVC.