Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled exception 0xE0434352 #43

Closed
jpeg729 opened this issue Jul 8, 2017 · 3 comments
Closed

Unhandled exception 0xE0434352 #43

jpeg729 opened this issue Jul 8, 2017 · 3 comments

Comments

@jpeg729
Copy link

jpeg729 commented Jul 8, 2017

I just spent HOURS debugging the following problem.

My DLL stopped working after some code changes. There was this one function call that would always cause an unhandled exception regardless of my error handling.

Do you see the error?

[DllExport("DoStuff", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static bool DoStuff([MarshalAs(UnmanagedType.LPWStr)] string inp1, [MarshalAs(UnmanagedType.LPWStr)] string inp2, double inp3, double inp4)
{
    try
    {
        return ResultOfDoingStuff(inp1, inp2, inp3, inp4);
    }
    catch
    {
        return false;
    }
}

Note that as the entire function body is enclosed in a try block, and as the corresponding catch is nigh on empty, there doesn't seem to be any code that could cause an exception.

Any ideas?

No? Then compare lines 2 and 3. According to line 2 the output is marshalled as a string pointer, but according to line 3 the output is a bool. It compiles beautifully, no mess, no fuss, and then it crashes horribly for a nigh on undetectable reason.

I have no idea how DLLExport works, so I don't know if a warning or error would be easy to implement. In any case let this be a warning to future passers by: "Marshall only when necessary."

@3F
Copy link
Owner

3F commented Jul 8, 2017

@jpeg729 You should use pointer to allocated string. I already gave an examples for Java & C++ here:

@jpeg729
Copy link
Author

jpeg729 commented Jul 8, 2017

You misunderstand me... I was not asking a question.

My function returns a bool and is supposed to return a bool. If however I make the mistake of adding the directive to marshall the return value as a string pointer [return: MarshalAs(UnmanagedType.LPWStr)], even though it is a bool, then that is when things go funny.

A stupid mistake, I know. So I posted it hoping that others would profit from my experience.

I would have lost many fewer hours debugging this problem had there been a warning saying that a bool return value should not be marshalled as a string pointer.

@3F
Copy link
Owner

3F commented Jul 8, 2017

I was not asking a question. ... So I posted it hoping that others would profit from my experience.

It exactly related to question anyway, and as a tip for other guys. Btw, I recommend to update title for clarify.

In general the PInvoke-mechanism does not support complex types at all. You should use IntPtr instead of this. The MarshalAs attribute affects for CLR to marshal the parameters and return values when calling an unmanaged proc from C#. So you can simply use any pointers with string str = (WCharPtr)ptr etc., and be a happy.

I would have lost many fewer hours debugging this

Well, I can try to write some detection of this before final generated binaries, but ... I hope that simply keeping of this in your mind will be not so hard for any type of developments :) However, if it's still is needed by someone, just create new issue about this feature-request, it will be considered later.

@3F 3F closed this as completed Jul 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants