DllImport, вызывающий исключение нарушения прав доступа - PullRequest
0 голосов
/ 28 июня 2018

Заголовок C dll таков:

HRESULT App_Process(char *FileName, char *Output, const bool& LogInformation);

Мой C # DllImport выглядит так:

[DllImport("App.dll")]
public static extern Int32 App_Process(
    [MarshalAs(UnmanagedType.LPStr)]string FileName,
    [MarshalAs(UnmanagedType.LPStr)]string Output,
    [MarshalAs(UnmanagedType.Bool)]bool LogInformation);

Исключение составляет:

var result = App_Process("MyFile.txt", "Output.txt", true);

System.AccessViolationException: попытка чтения или записи защищена объем памяти. Это часто указывает на то, что другая память повреждена.

Теперь странно, что метод успешно выполняет все, что должен был делать.

Есть идеи?

1 Ответ

0 голосов
/ 28 июня 2018

Оригинальный ответ

Последний параметр метода extern должен быть ref bool, а не bool, учитывая, что в заголовке DLL есть параметр типа const bool&:

// Parameter names changed to be idiomatic for C#
[DllImport("App.dll")]
public static extern Int32 App_Process(
    [MarshalAs(UnmanagedType.LPStr)] string fileName,
    [MarshalAs(UnmanagedType.LPStr)] string output,
    [MarshalAs(UnmanagedType.Bool)] ref bool logInformation);

С C # 7.2 я подозреваю, что вы могли бы использовать in вместо ref, что упростило бы вызов метода:

// Parameter names changed to be idiomatic for C#
[DllImport("App.dll")]
public static extern Int32 App_Process(
    [MarshalAs(UnmanagedType.LPStr)] string fileName,
    [MarshalAs(UnmanagedType.LPStr)] string output,
    [MarshalAs(UnmanagedType.Bool)] in bool logInformation);

Обновление

(из комментария Ганса Пассанта)

Это не код C, так как bool& действителен только в C ++. Это делает очень вероятным, что аргумент должен быть обозначен как [MarshalAs(UnmanagedType.U1)]. Дважды проверьте с sizeof(bool) в собственном коде. Но вы должны поговорить с автором DLL, так как const bool& не имеет никакого смысла. Нет смысла передавать bool по ссылке, но не разрешать коду обновлять его.

...