Browse Source

Fixed a crash on Mono when marshalling types with no fields.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/520/head
Dimitar Dobrev 10 years ago
parent
commit
9d78f5386d
  1. 14
      src/Generator/Passes/CheckAbiParameters.cs
  2. 6
      tests/Basic/Basic.Tests.cs
  3. 5
      tests/Basic/Basic.cpp
  4. 10
      tests/Basic/Basic.h

14
src/Generator/Passes/CheckAbiParameters.cs

@ -12,6 +12,9 @@ namespace CppSharp.Passes @@ -12,6 +12,9 @@ namespace CppSharp.Passes
/// and use that to call the function instead. In the case of parameters
/// then the type of that parameter is converted to a pointer.
///
/// Furthermore, there's at least one ABI (System V) that gives to empty structs
/// size 1 in C++ and size 0 in C. The former causes crashes in older versions of Mono.
///
/// Itanium ABI reference (3.1.4 Return values):
/// http://refspecs.linux-foundation.org/cxxabi-1.83.html#calls
///
@ -20,6 +23,17 @@ namespace CppSharp.Passes @@ -20,6 +23,17 @@ namespace CppSharp.Passes
/// </summary>
public class CheckAbiParameters : TranslationUnitPass
{
public override bool VisitClassDecl(Class @class)
{
if (!base.VisitClassDecl(@class))
return false;
if (@class.Fields.Count == 0)
@class.Layout.Size = @class.Layout.DataSize = 0;
return true;
}
public override bool VisitFunctionDecl(Function function)
{
if (!VisitDeclaration(function))

6
tests/Basic/Basic.Tests.cs

@ -516,5 +516,11 @@ public class BasicTests : GeneratorTestFixture @@ -516,5 +516,11 @@ public class BasicTests : GeneratorTestFixture
{
Assert.AreEqual(10, Foo.@unsafe);
}
[Test]
public void TestMarshallingEmptyType()
{
var empty = new ReturnsEmpty().Empty;
}
}

5
tests/Basic/Basic.cpp

@ -425,3 +425,8 @@ int ChangedAccessOfInheritedProperty::getProperty() @@ -425,3 +425,8 @@ int ChangedAccessOfInheritedProperty::getProperty()
void ChangedAccessOfInheritedProperty::setProperty(int value)
{
}
Empty ReturnsEmpty::getEmpty()
{
return Empty();
}

10
tests/Basic/Basic.h

@ -787,3 +787,13 @@ protected: @@ -787,3 +787,13 @@ protected:
int getProperty();
void setProperty(int value);
};
class DLL_API Empty
{
};
class DLL_API ReturnsEmpty
{
public:
Empty getEmpty();
};

Loading…
Cancel
Save