Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshaling fixed size enum array in C#

I'm trying to marshal a fix sized array enum in C#.

Here is the native declaration in C:

typedef enum GPIO_Dir
{
    GPIO_OUTPUT =0,
    GPIO_INPUT,
}
GPIO_Dir;
FT4222_STATUS FT4222_GPIO_Init(FT_HANDLE ftHandle, GPIO_Dir gpioDir[4]);

Here is the example of code:

GPIO_Dir gpioDir[4];
gpioDir[0] = GPIO_OUTPUT;
gpioDir[1] = GPIO_OUTPUT;
gpioDir[2] = GPIO_OUTPUT;
gpioDir[3] = GPIO_OUTPUT;

FT4222_GPIO_Init(ftHandle, gpioDir);

The native code is working without any issue.

I have no issue to mashal the FT_HANDLE.

I have tried multiple options but it seems that nothing is really working. I have been trying without success multiple definitions like:

[DllImport("LibFT4222.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern FtStatus FT4222_GPIO_Init(IntPtr ftHandle, [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] GpioPinMode[] gpioDir);

I've been as well trying to decorate the array to pass:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
private GpioPinMode[] _gpioDirections = new GpioPinMode[PinCountConst];

GpioPinMode is a simple enum:

internal enum GpioPinMode : int
{        
    Output = 0,
    Input,
}

Thanks a lot.

like image 807
Laurent Ellerbach Avatar asked Mar 21 '26 15:03

Laurent Ellerbach


1 Answers

I have made a very simple program to send the enum[] to C++. C++ will read the enum and write to a file what it currently is. Right now it doesn't return anything as I do not know what FtStatus can be.

C#

internal enum GpioPinMode : int
{
    Output = 0,
    Input,
}

[DllImport("library.dll", EntryPoint = "FT4222_GPIO_Init", CallingConvention = CallingConvention.Cdecl)]
public static extern void FT4222_GPIO_Init(GpioPinMode[] gpioDir);

static void Main(string[] args)
{
    GpioPinMode[] gpioDir = new GpioPinMode[4];

    gpioDir[0] = GpioPinMode.Input;
    gpioDir[1] = GpioPinMode.Input;
    gpioDir[2] = GpioPinMode.Output;
    gpioDir[3] = GpioPinMode.Output;

    FT4222_GPIO_Init(gpioDir);
}

C++

#include "pch.h"
#include <fstream>

#define DllExport extern "C" __declspec(dllexport)

typedef enum GPIO_Dir
{
    GPIO_OUTPUT = 0,
    GPIO_INPUT,
}
GPIO_Dir;

DllExport void FT4222_GPIO_Init(GPIO_Dir gpioDir[4])
{
    std::ofstream myfile;

    myfile.open("File.txt", std::ios::out);

    if (gpioDir[0] == GPIO_INPUT)
        myfile << 0 << ": input" << std::endl;
    else
        myfile << 0 << ": output" << std::endl;

    if (gpioDir[1] == GPIO_INPUT)
        myfile << 1 << ": input" << std::endl;
    else
        myfile << 1 << ": output" << std::endl;

    if (gpioDir[2] == GPIO_INPUT)
        myfile << 2 << ": input" << std::endl;
    else
        myfile << 2 << ": output" << std::endl;

    if (gpioDir[3] == GPIO_INPUT)
        myfile << 3 << ": input" << std::endl;
    else
        myfile << 3 << ": output" << std::endl;
}

I hope this gives you a sense of how this can be done.

like image 177
wes Avatar answered Mar 23 '26 04:03

wes