public static extern int MyDllFunction(
     int param1,
     // We want this to become a C-style boolean
     // (false == 0, true != 0)
     [MarshalAs(UnmanagedType.Bool)]
     bool param2,
     // We want the dll to write to our struct, and to be
     // able to get the data written to it back we need to
     // specify the Out-attribute. If we were just feeding the
     // parameter to the dll we could just use the In-attribute
     // instead, or combine them if we want to achieve both.
     [Out, MarshalAs(UnmanagedType.LPStruct)]
     MyDllStruct resultStruct
     );
    // Calls the MyDllInterface.MyDllFunction and returns
    // the resulting struct. If an error occured, an
    // exception is thrown.
    public MyDllStruct CallFunction(int param1, bool param2)
    {
        MyDllStruct result = new MyDllStruct();

        int errorCode = MyDllInterface.MyDllFunction(
            param1, param2, result);

        if (errorCode < 0)
        {
            throw new Exception(String.Format(
                                    "We got an error with code {0}. Message: ",
                                    errorCode, MyDllInterface.mydll_get_errormsg()));
        }
        return(result);
    }