C# Подключение dll, Marshaling

143
06 февраля 2018, 06:22

C#. marshaling. CallBacks. Struct.

Друзья, спасайте, есть некая dll написанная на C++, мучаюсь с подключением этой либы, мне кажется что проблема в маршализации. Я привел свой фрагмент класса обертки, верно ли я промаршализировал все переменные? Рассчитываю на ваш свежий взгляд, потому что у меня уже начались какие то танцы с бубнами.

Есть структура, в ней содержится структура с колбеками (указателями на них). Она же передается в фунцию initialize. На всякий случай привожу полны код, необходимый для работы, без абстрактных примеров.

C++ Фрагмент заголовочных файлов самой dll

typedef enum
{
    MIFARE_KEY_A,
    MIFARE_KEY_B
}
MifareKeyType;
typedef enum
{
    OPERATION_OK,
    OPERATION_ERR
}
CallbackResult;
typedef CallbackResult (*MifareAuth)(unsigned char blockNumber, MifareKeyType keyType, const unsigned char * mifareKey);
typedef CallbackResult (*MifareReadBlock)(unsigned char blockNum, unsigned char * blockData); 
typedef CallbackResult (*MifareWriteBlock)(unsigned char blockNum, const unsigned char * blockData); 
typedef CallbackResult (*SendAPDU)(const unsigned char * apdu, unsigned long apduLength,
                                    unsigned char * response, unsigned long maxResponseLength, unsigned long * responseLength);
typedef struct
{
    SendAPDU            sendAPDU;
    MifareAuth          mifareAuth;
    MifareReadBlock     mifareReadBlock;
    MifareWriteBlock    mifareWriteBlock;
}
SetOfCallbacks;
COM_FTC_UTCA_LIB_EXPORT int initialize(const UContext * context);

C# Класс обертка:

class TestDLLClass
{
    public TestDLLClass()
    {
        UContext context = new UContext();
        context.callbacks = new SetOfCallbacks();
        // присваиваю колбкеки, для читабельности использую лямбду
        MifareAuth ma = (blockNumber, keyType, mifareKey) =>
        {
            Console.WriteLine("MifareAuth");
            Console.WriteLine($" -blockNumber : {blockNumber} \n -keyType : {keyType} \n -mifareKey : {mifareKey}");
            return CallbackResult.OPERATION_OK;
        };
        context.callbacks.mifareAuth = ma;
        MifareReadBlock mrb = (blockNumber, blockData) =>
        {
            Console.WriteLine("MifareReadBlock");
            return CallbackResult.OPERATION_OK;
        };
        context.callbacks.mifareReadBlock = mrb;
        MifareWriteBlock mwb = (blockNum, blockData) =>
        {
            Console.WriteLine("MifareWriteBlock");
            return CallbackResult.OPERATION_OK;
        };
        context.callbacks.mifareWriteBlock = mwb;
        SendAPDU sApdu = (apdu, apduLength, response, maxResponseLength, responseLength) =>
        {
            Console.WriteLine("SendAPDU");
            return CallbackResult.OPERATION_OK;
        };
        context.callbacks.sendAPDU = sApdu;
        // Вот она моя самая проблемная функция
        int result = initialize(ref context);
        string s = result.ToString("X");
        Console.ReadKey();
    }

    #region Функции длл
    [StructLayout(LayoutKind.Sequential)]
    public struct UContext
    {
        [MarshalAs(UnmanagedType.Struct)]
        public SetOfCallbacks callbacks;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct SetOfCallbacks
    {
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public MifareAuth mifareAuth;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public MifareReadBlock mifareReadBlock;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public MifareWriteBlock mifareWriteBlock;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public SendAPDU sendAPDU;
    }

    // typedef CallbackResult(*MifareAuth)(unsigned char blockNumber, MifareKeyType keyType, const unsigned char* mifareKey);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public delegate CallbackResult MifareAuth(byte blockNumber, MifareKeyType keyType, IntPtr mifareKey);
    //typedef CallbackResult(*MifareReadBlock)(unsigned char blockNum, unsigned char* blockData);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate CallbackResult MifareReadBlock(byte blockNumber, StringBuilder blockData);
    //typedef CallbackResult (*MifareWriteBlock)(unsigned char blockNum, const unsigned char * blockData);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate CallbackResult MifareWriteBlock(byte blockNum, StringBuilder blockData);
    //typedef CallbackResult(*SendAPDU)(const unsigned char* apdu, unsigned long apduLength, unsigned char* response, unsigned long maxResponseLength, unsigned long* responseLength);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate CallbackResult SendAPDU(StringBuilder apdu, ulong apduLength, StringBuilder response, ulong maxResponseLength, IntPtr responseLength);

    //COM_FTC_UTCA_LIB_EXPORT void getUtcaVersion(char* versionString, unsigned long maxStrLength);
    [DllImport(@"com_ftc_utca_lib_s.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern void getUtcaVersion(StringBuilder versionString, UInt32 maxStrLength);
    //COM_FTC_UTCA_LIB_EXPORT int initialize(const UContext * context);
    [DllImport(@"com_ftc_utca_lib_s.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public static extern int initialize(/*[MarshalAs(UnmanagedType.Struct)]*/ ref UContext context);

    public enum CallbackResult
    {
        OPERATION_OK,
        OPERATION_ERR
    }

    public enum MifareKeyType
    {
        MIFARE_KEY_A,
        MIFARE_KEY_B
    }
    #endregion
}
READ ALSO
c# удалить разрешения пользователя

c# удалить разрешения пользователя

Нужно на папку программно удалять разрешения определенного пользователяНашел пример на MSDN

158
C#Web сервис подключение

C#Web сервис подключение

Вопрос такойУ меня есть класс веб службы:

132
c# не работает try catch

c# не работает try catch

В программе не работает блок try - catchВот код:

143
Параллельная сортировка пузырьком на C#

Параллельная сортировка пузырьком на C#

Всем доброго времени сутокНесколько часов убил на то, чтобы понять, как работают потоки на C#, однако ничего толком не вышло

131