Я сейчас играю с совместимостью с 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