none
Call to DllImport throws SEHException RRS feed

  • Question

  • Hi

    I have a unmanaged C++ Dll exporting some functions and a managed C# helper class importing the functions using DllImportAttribute. Every time I try to call one of these functions vshost32.exe dies with a SEHException. The exception can't be resolved so I have no clue what went wrong.


    test.h

    bool TestCall(int number);


    test.cpp

    #include "test.h"

    bool TestCall(int number)
    {
        return (number > 10);
    }


    test.def

    EXPORTS
        TestCall


    Program.cs

    using System;
    using System.Runtime.InteropServices;

    namespace TestApp
    {
        public class TestUtil
        {
            [
    DllImport("TestDll.dll")]
            public static extern bool TestDll(int number);
        }

        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(TestUtil.TestDll(15).ToString());
                Console.ReadLine();
            }
        }
    }


    The call to TestUtil.TestDll(15) throws an SEHException. Does anyone know why?

    thanks


    Monday, December 1, 2008 4:53 PM

Answers

  • SEHExceptions are raised from unmanamaged code, which in turn are usually the product of memory faults or calls to RaiseException(). In the case where the .NET runtime understands the error code, it will remap the exception to a more readable one - for example, OutOfMemoryException, etc. But if the .NET runtime doesn't understand the error code, you get a generic SEHExcpetion.

    The SEHException should give you a hex error code, which you can use to discover a more specific OS error message.

    My gut feeling in this case though, is that the unmanaged C++ export function isn't using a calling convention that the .NET runtime assumes to be the default. In this case, if i remember correctly, unless specifically labeled, C# assumes StdCall - which is what the vast majority of the OS API functions use. Using the wrong calling convention can adversely affect the state of the call stack when switching back and forth between managed and unamanaged code, and there's no way to recover from that.

    So the first place i'd look here is to either change the C++ function to use StdCall, *OR* to change the C# export declaration to specify the calling convention used in the C++ function (in VC++, I believe the default is CDecl).
    -Rob Teixeira
    • Marked as answer by TitanCerberus Tuesday, December 2, 2008 9:32 AM
    Monday, December 1, 2008 7:30 PM

All replies

  • SEHExceptions are raised from unmanamaged code, which in turn are usually the product of memory faults or calls to RaiseException(). In the case where the .NET runtime understands the error code, it will remap the exception to a more readable one - for example, OutOfMemoryException, etc. But if the .NET runtime doesn't understand the error code, you get a generic SEHExcpetion.

    The SEHException should give you a hex error code, which you can use to discover a more specific OS error message.

    My gut feeling in this case though, is that the unmanaged C++ export function isn't using a calling convention that the .NET runtime assumes to be the default. In this case, if i remember correctly, unless specifically labeled, C# assumes StdCall - which is what the vast majority of the OS API functions use. Using the wrong calling convention can adversely affect the state of the call stack when switching back and forth between managed and unamanaged code, and there's no way to recover from that.

    So the first place i'd look here is to either change the C++ function to use StdCall, *OR* to change the C# export declaration to specify the calling convention used in the C++ function (in VC++, I believe the default is CDecl).
    -Rob Teixeira
    • Marked as answer by TitanCerberus Tuesday, December 2, 2008 9:32 AM
    Monday, December 1, 2008 7:30 PM
  • Agreed, the calling convention is definitely wrong.  There's an MDA for that though (pInvokeStackImbalance), it should diagnose that problem.  Something goes wrong before that.  Use the debugger to find out what's wrong: Debug + Exceptions, turn on the Thrown flag for Win32 Exceptions.
    Hans Passant.
    Tuesday, December 2, 2008 12:52 AM
    Moderator
  • I added stdcall on both sides and it works. Thanks a lot.
    Tuesday, December 2, 2008 9:36 AM