2014-01-15 3 views
-2

У меня есть эта функция C внутри dll, которую я вызываю из VB.Net.Почему логическая функция, возвращающая false, возвращает true

код C:

extern "C" { 
    __declspec(dllexport) bool __stdcall C(bool ret); 
} 

extern bool __stdcall C(bool ret){ 
    return ret; 
} 

Вот мой VB.Net код, который вызывает выше:

Imports System.Runtime.InteropServices 

Module Module1 

    <DllImport("foo.dll", CallingConvention:=CallingConvention.StdCall)> _ 
    Private Function C(ByVal param As Boolean) As Boolean 
    End Function 

    Sub Main() 
     System.Console.WriteLine("C(False): {0}", C(False)) 
     System.Console.WriteLine("C(True): {0}", C(True)) 
    End Sub 

End Module 

Когда я запускаю приведенный выше код, я получаю:

C(False): True 
C(True): True 

Кажется, мы фактически не возвращаем значение от C(), но скорее мы возвращаем тот факт, что C() успешно работает.

Почему C() всегда возвращается true? И когда C() не будет успешно работать?

Если у вас есть какая-либо другая информация об этом явлении, пожалуйста, дайте мне свой ответ :) Это все было в моей голове. Приветствия.

+6

Я понятия не имею, что вы просите. Пожалуйста, перефразируйте свой вопрос. Чтобы уточнить, вы проверяете возвращаемое значение функции .. потому что оператор является условным выражением, а значение, которое находится там, - это логическое возвращаемое значение функции. –

+0

Вы указываете, что мы фактически возвращаем значение из C(), которое мы проверяем, успешно ли выполняется C(). ". Это не так, как сказал Саймон. Путаница может исходить из общего соглашения на многих платформах, чтобы вернуть значение, которое будет оцениваться как true, если вызов функции выполняет то, что он должен был делать, и возвращать то, что будет оцениваться как false, если вызов функции завершится неудачно. Значение все еще возвращается, просто значение следует за полезным соглашением. –

+0

Если функция * не работает «успешно», вы узнаете об этом, когда ваша программа поймает исключение или сбой. – paddy

ответ

2

Почему C() всегда возвращает true?

Я нашел проблему Microsoft Connect, который говорит о возвращении bool, и почему он ведет себя так, как это делает. Это от вопроса Native C++ function returning bool always return true in .NET Interop:

вам нужно украсить P/Invoke декларации [Возврат: MarshalAs (UnmanagedType.I1)]. Bool marshals to Win32 BOOL - это 4-байтовое значение .... Ваша функция возвращает 1-байт bool ... так что любой мусор в верхних 24 битах ... будет интерпретироваться как «истина» маршалингом слой.

Итак, другими словами, тип В. Б. Boolean неправильно получение сопоставлен с Win 32 BOOL (4 байта), которая не является такой же, как C логическое значение (1 байт).

Чтобы исправить это, вы можете сделать один из этих двух вещей:

Вариант 1 - Изменение VB P/Invoke Подпись

Вы можете сказать, код сортировочной для отображения на один байт bool.

Эта линия в VB P/Invoke подпись:

 
Private Function C(ByVal param As Boolean) As Boolean 

должен быть изменен на:

 
Private Function C(<MarshalAs(UnmanagedType.I1)> ByVal param As Boolean) As _ 
<MarshalAs(UnmanagedType.I1)> Boolean 

Вариант 2 - Изменение C сигнатура функции

Вы можете изменить C один байт bool типа для Win 32 четырехбайтовый BOOL, а именно:

 
extern "C" { 
    __declspec(dllexport) BOOL __stdcall C(BOOL ret); 
} 

extern BOOL __stdcall C(BOOL ret){ 
    return ret; 
} 

Результаты

Если я запустить программу либо один из указанных выше изменений, выход:

C(False): False 
C(True): True 

возвращаемые значения в настоящее время отражают значения параметров.


И когда бы C() не работает успешно?

Ваш код, как написано, обычно успешно работает. Единственный случай, когда я могу думать, что он не работает, - это код VB.Net не может найти бинарный файл C. В этом случае будет выбрано исключение; если вы не поймаете исключение, ваше приложение будет прекращено.

+0

Отличный ответ, и он заслуживает большего, потому что он поставил вопрос в отличный вопрос. –

Смежные вопросы