Подключение dll. Маршализация - C#/.NET 4.x

Узнай цену своей работы

Формулировка задачи:

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
 
}

Решение задачи: «Подключение dll. Маршализация»

textual
Листинг программы
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;

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.333 из 5
Похожие ответы