bool против BOOLEAN в управляемых прототипах - PullRequest
3 голосов
/ 16 сентября 2009

Я пытаюсь создать управляемый прототип в C # для функции API [CreateSymbolicLink][1]. Прототип в WinBase.h:

BOOLEAN APIENTRY CreateSymbolicLink (
    __in LPCWSTR lpSymlinkFileName,
    __in LPCWSTR lpTargetFileName,
    __in DWORD dwFlags
    );

И BOOLEAN определяется как BYTE в WinNT.h. Хорошо. Итак, мой управляемый прототип должен быть:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CreateSymbolicLink(string SymlinkFileName, string TargetFileName, UInt32 Flags);

По крайней мере, я бы так подумал. bool это просто псевдоним для System.Boolean, однобайтовое значение. Но, похоже, это не работает.

Я выполняю этот код:

bool retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);

Возвращает true. Но символическая ссылка не создана. Причина, по которой он не создан, заключается в том, что я не работаю с повышенными привилегиями. GetLastError возвращает 1314, что в соответствии с WinError.h означает, что у меня нет необходимых разрешений. Как и ожидалось. Но почему мое возвращаемое значение true?

Любопытно, если я изменю управляемый прототип на:

static extern byte CreateSymbolicLink(string SymlinkFileName, string TargetFileName, UInt32 Flags);

и мой код:

byte retval = CreateSymbolicLink(LinkFilename, TargetFilename, 0);

Затем я получаю ожидаемый результат: retval содержит 0, что означает, что функция не выполнена.

Наверное, мой главный вопрос: почему bool не работает для BOOLEAN возвращаемых значений?

Ответы [ 2 ]

4 голосов
/ 16 сентября 2009

Отметьте возвращаемое значение соответствующим атрибутом MarshalAs:

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool CreateSymbolicLink(string SymlinkFileName, 
    string TargetFileName, UInt32 Flags);

Маршаллинг по умолчанию для bool из нативного в управляемый код составляет 4 байта - вы, вероятно, вернули true для вашего исходного bool, потому что один из ошибочно распределенных байтов стека был ненулевым. (Я догадываюсь об этой последней части.)

1 голос
/ 16 сентября 2009

PInvoke с логическими типами может привести к неожиданным результатам из-за различий между нативными и управляемыми логическими переменными. Я написал статью в блоге на эту тему с подробным описанием различий и правильных способов объединения различных типов

Бен М имеет правильный ответ в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...