DllImport causing access violation exception
DllImport causing access violation exception
The C dll header is this:
HRESULT App_Process(char *FileName, char *Output, const bool& LogInformation);
My C# DllImport looks like this:
[DllImport("App.dll")]
public static extern Int32 App_Process(
[MarshalAs(UnmanagedType.LPStr)]string FileName,
[MarshalAs(UnmanagedType.LPStr)]string Output,
[MarshalAs(UnmanagedType.Bool)]bool LogInformation);
The exception is:
var result = App_Process("MyFile.txt", "Output.txt", true);
System.AccessViolationException: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
Now the strange this is that the method is successfully doing everything its supposed to do.
Any ideas?
ref bool
All the
MarshalAs
attributes are pointless, merely restating the defaults as they do. Last param is ref bool
. Calling convention is unknown. And it looks like the two string parameters could be output parameters because they are char*
rather than const char*
. I suggest that you read the documentation for this library before attempting to call it.– David Heffernan
Jun 28 at 10:47
MarshalAs
ref bool
char*
const char*
@DaisyShipton Yes the ref bool solved the problem. Post it as an answer please. Thanks.
– CathalMF
Jun 28 at 10:53
1 Answer
1
Original answer
The last parameter of the extern method should be a ref bool
rather than bool
, given that the DLL header has a parameter of type const bool&
:
ref bool
bool
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);
With C# 7.2 I suspect you could use in
instead of ref
, which would make the method simpler to call:
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);
Update
(From the comment from Hans Passant)
This is not C code, as bool&
is only valid in C++. That makes it very likely that the argument needs to be marshalled as [MarshalAs(UnmanagedType.U1)]
. Double-check with sizeof(bool)
in the native code. But you should talk to the author of the DLL, as const bool&
makes no sense at all. There's no point in passing a bool by reference but then not allowing the code to update it.
bool&
[MarshalAs(UnmanagedType.U1)]
sizeof(bool)
const bool&
This is not C code, bool& is only valid in C++. Which makes it very likely that the argument needs [MarshalAs(UnamagedType.U1)]. Double-check with sizeof(bool) in the native code. The OP really needs to talk to the author, const bool& makes no sense at all. No point in passing a bool by reference but then not allowing to update it.
– Hans Passant
Jun 29 at 19:30
@HansPassant: I've updated the answer to just include your comment almost verbatim. We'll see if the OP sees it...
– Daisy Shipton
Jun 30 at 7:24
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Perhaps last parameter should be a
ref bool
?– Daisy Shipton
Jun 28 at 10:44