Как получить совместимость C / C ++ <-> C # с массивами bool? - PullRequest
0 голосов
/ 02 сентября 2018

Я сейчас играю с совместимостью с C ++ и особенно с C #. У меня есть C ++ DLL, содержащая API в стиле C, который я хочу сделать доступным для C #, и большую часть времени я обнаруживаю, что это не так уж плохо. Тем не менее, я ужасно провожу время с массивами bool. Приведенный ниже код и выходные данные должны объяснить проблему.

Массив bool может быть передан, проверен и изменен, но любые изменения не остаются в коде C # после возврата из библиотеки DLL. В отличие от этого, если вы попробуете это, скажем, с двойным массивом, он работает отлично. Вам даже не нужно использовать атрибут MarshalAs в объявлении, и вы можете передать его, как описано ниже, с помощью TestMethod19. Я считаю, что причина в том, что размер bool на C # составляет 4 байта, а на C ++ - 1 байт (проверяется с помощью Marshal.SizeOf и sizeof соответственно), но что я могу сделать, чтобы это работало?

Передача массива Bool в C ++ Код из C # не является дубликатом. Ответы говорят маршалу как I1, что, как показывают мои тесты, не работает. Я думаю, что этот вопрос был предназначен для массива bool в переменной, которая предназначена только для чтения. Однако я также ищу, чтобы этот массив был переменной out.

C ++ Декларация .h:

extern "C" DECLSPEC void TestMethod15(bool* d);

Определение C ++ .cpp:

void TestMethod15(bool* d)
{
    cout << "Inside Test Method 15.  ";
    cout << "Printing bool array param: ";

    for (int i = 0; i < 5; i++)
    {
        cout << d[i] << ",";
    }

    cout << endl << "Putting values in the bool array: ";

    for (int i = 0; i < 5; i++)
    {
        d[i] = i % 2 == 0;
        cout << d[i] << ",";
    }
    cout << endl;
}

C # декларации

public class QuizzerEngine
{
    [DllImport("QuizzerEngine.DLL", CallingConvention = CallingConvention.Cdecl)]
    public static extern void TestMethod15(
        [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1)] bool[] bAr);

    [DllImport("QuizzerEngine.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "TestMethod15")]
    public static extern void TestMethod16(
        [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)] bool[] bAr);

    [DllImport("QuizzerEngine.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "TestMethod15")]
    public static extern void TestMethod17(
        [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Bool)] bool[] bAr);

    [DllImport("QuizzerEngine.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "TestMethod15")]
    public static extern void TestMethod18(
        [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.VariantBool)] bool[] bAr);

    [DllImport("QuizzerEngine.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "TestMethod15")]
    public static extern void TestMethod19(
        bool[] bAr);
}

C # Звонки

{
    bool[] boolArray = new bool[5];
    boolArray[1] = true;
    QuizzerEngine.TestMethod15(boolArray);
    Console.WriteLine("After TM15: {0},{1},{2},{3},{4}\n", boolArray[0], boolArray[1], boolArray[2], boolArray[3], boolArray[4]);
}
{
    bool[] boolArray = new bool[5];
    boolArray[1] = true;
    QuizzerEngine.TestMethod16(boolArray);
    Console.WriteLine("After TM16: {0},{1},{2},{3},{4}\n", boolArray[0], boolArray[1], boolArray[2], boolArray[3], boolArray[4]);
}
{
    bool[] boolArray = new bool[5];
    boolArray[1] = true;
    QuizzerEngine.TestMethod17(boolArray);
    Console.WriteLine("After TM17: {0},{1},{2},{3},{4}\n", boolArray[0], boolArray[1], boolArray[2], boolArray[3], boolArray[4]);
}
{
    bool[] boolArray = new bool[5];
    boolArray[1] = true;
    QuizzerEngine.TestMethod18(boolArray);
    Console.WriteLine("After TM18: {0},{1},{2},{3},{4}\n", boolArray[0], boolArray[1], boolArray[2], boolArray[3], boolArray[4]);
}
{
    bool[] boolArray = new bool[5];
    boolArray[1] = true;
    QuizzerEngine.TestMethod18(boolArray);
    Console.WriteLine("After TM19: {0},{1},{2},{3},{4}\n", boolArray[0], boolArray[1], boolArray[2], boolArray[3], boolArray[4]);
}

Выход:

Inside Test Method 15.  Printing bool array param: 0,1,0,0,0,
Putting values in the bool array: 1,0,1,0,1,
After TM15: False,True,False,False,False

Inside Test Method 15.  Printing bool array param: 0,1,0,0,0,
Putting values in the bool array: 1,0,1,0,1,
After TM16: False,True,False,False,False

Inside Test Method 15.  Printing bool array param: 0,0,0,0,1,
Putting values in the bool array: 1,0,1,0,1,
After TM17: False,True,False,False,False

Inside Test Method 15.  Printing bool array param: 0,0,255,255,0,
Putting values in the bool array: 1,0,1,0,1,
After TM18: False,True,False,False,False

Inside Test Method 15.  Printing bool array param: 0,0,255,255,0,
Putting values in the bool array: 1,0,1,0,1,
After TM19: False,True,False,False,False
...