PInvoke сортировка целых чисел, возвращающих неверный результат - PullRequest
1 голос
/ 16 декабря 2011

У меня очень простая функция в неуправляемой DLL, но я не получаю правильное возвращаемое значение из нее.

Я могу подтвердить, что общий механизм PInvoke работает с одной функцией в моей C DLL:

/* Return an integer */
extern "C" __declspec(dllexport) long get_num()
{
    return 42;
}

Я называю вышеупомянутую неуправляемую точку входа из C # .NET:

[DllImport("My_C_DLL.dll")]
extern static long get_num();
// ...
long ans = get_num();
Console.WriteLine("The answer is {0}.", ans);

Это работает нормально, но передача параметров маршалирования другой функции в DLL возвращает неверный результат:

/* Add two integers */
extern "C" __declspec(dllexport) long add_num(long a, long b)
{
    long sum = a + b;

    return sum;
}

Вызывается из C # как:

[DllImport("My_C_DLL.dll")]
extern static long add_num(long a, long b);

long a = 6, b = 12;
long sum = add_num(a, b);
Console.WriteLine("The answer is {0}.", sum);

Это возвращает мне результат «6», или что бы я ни установил для входного значения a .

Я предполагаю, что неправильное распределение входных значений портит стек вызовов, что приводит к неверному возвращаемому значению, но где ошибка?

Ответы [ 3 ]

3 голосов
/ 16 декабря 2011

Две проблемы здесь.Прежде всего, C # long не соответствует C long.В Windows длина C составляет 32 бита.Используйте int в своем коде C # для соответствия с C long.

Другая проблема заключается в том, что соглашения о вызовах, вероятно, не совпадают.Скорее всего, у вас есть cdecl в вашей C DLL, но C # по умолчанию stdcall.Исправьте это, изменив ваш p ​​/ invoke.

[DllImport("My_C_DLL.dll", CallingConvention=CallingConvention.Cdecl)]
1 голос
/ 16 декабря 2011

У вас может быть проблема с управляемой частью, определяющей long как 64-разрядное целое число, в то время как ваш компилятор C определяет его как 32-разрядное целое число.

Вы можете изменить long на int в своем коде C #, изменить long на int64_t в своем коде Cили принудительно назначить 32-разрядную сортировку с помощью MarshalAs (UnmanagedType.I4) (принудительная сортировка только в случае сбоя всех остальных идей)

1 голос
/ 16 декабря 2011

Вы строите неуправляемую DLL как 32-битную или 64-битную? Помните, что тип long в C # совпадает с System.Int64. Это может быть источником вашей проблемы с сортировкой. Если ваша DLL 32-битная, попробуйте изменить код C # на:

[DllImport("MY_C_DLL.dll")]
extern static int add_num(int a, int b);
...