Browse Source

Used packing when laying marshalling structures out sequentially.

Fixes https://github.com/mono/CppSharp/issues/772.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/876/head
ktopouzi 8 years ago committed by Dimitar Dobrev
parent
commit
75b96143d2
  1. 2
      src/CppParser/Parser.cpp
  2. 3
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 17
      tests/Common/Common.Tests.cs
  4. 36
      tests/Common/Common.cpp
  5. 40
      tests/Common/Common.h

2
src/CppParser/Parser.cpp

@ -3820,7 +3820,7 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D, @@ -3820,7 +3820,7 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D,
if (Attr->getKind() == clang::attr::Kind::MaxFieldAlignment)
{
auto MFA = cast<clang::MaxFieldAlignmentAttr>(Attr);
Decl->maxFieldAlignment = MFA->getAlignment();
Decl->maxFieldAlignment = MFA->getAlignment() / 8; // bits to bytes.
}
}
}

3
src/Generator/Generators/CSharp/CSharpSources.cs

@ -428,7 +428,8 @@ namespace CppSharp.Generators.CSharp @@ -428,7 +428,8 @@ namespace CppSharp.Generators.CSharp
PushBlock(BlockKind.InternalsClass);
if (!Options.GenerateSequentialLayout || @class.IsUnion)
WriteLine($"[StructLayout(LayoutKind.Explicit, Size = {@class.Layout.Size})]");
// no else because the layout is sequential for structures by default
else if (@class.MaxFieldAlignment > 0)
WriteLine($"[StructLayout(LayoutKind.Sequential, Pack = {@class.MaxFieldAlignment})]");
GenerateClassInternalHead(@class);
WriteStartBraceIndent();

17
tests/Common/Common.Tests.cs

@ -620,6 +620,23 @@ public class CommonTests : GeneratorTestFixture @@ -620,6 +620,23 @@ public class CommonTests : GeneratorTestFixture
Assert.IsFalse(differentConstOverloads == 5);
}
[Test]
public void TestPacking()
{
foreach (var testPacking in new TestPacking[] { new TestPacking1(), new TestPacking2(),
new TestPacking4(), new TestPacking8() })
{
testPacking.I1 = 2;
testPacking.I2 = 4;
testPacking.B = true;
Assert.That(testPacking.I1, Is.EqualTo(2));
Assert.That(testPacking.I2, Is.EqualTo(4));
Assert.That(testPacking.B, Is.EqualTo(true));
testPacking.Dispose();
}
}
[Test]
public void TestRenamingVariableNamedAfterKeyword()
{

36
tests/Common/Common.cpp

@ -1,6 +1,42 @@ @@ -1,6 +1,42 @@
#include "Common.h"
#include <string.h>
TestPacking::TestPacking()
{
}
TestPacking1::TestPacking1()
{
}
TestPacking1::~TestPacking1()
{
}
TestPacking2::TestPacking2()
{
}
TestPacking2::~TestPacking2()
{
}
TestPacking4::TestPacking4()
{
}
TestPacking4::~TestPacking4()
{
}
TestPacking8::TestPacking8()
{
}
TestPacking8::~TestPacking8()
{
}
Foo::Foo()
{
auto p = new int[4];

40
tests/Common/Common.h

@ -7,24 +7,46 @@ @@ -7,24 +7,46 @@
#include <string>
#include <vector>
#pragma pack(4)
class TestPacking
class DLL_API TestPacking
{
public:
int integer;
bool boolean;
double dble;
int i1;
int i2;
bool b;
TestPacking();
};
#pragma pack(1)
class DLL_API TestPacking1: public TestPacking
{
public:
TestPacking1();
~TestPacking1();
};
#pragma pack(2)
struct TestP
class DLL_API TestPacking2: public TestPacking
{
char b;
bool c;
double d;
public:
TestPacking2();
~TestPacking2();
};
#pragma pack(4)
class DLL_API TestPacking4: public TestPacking
{
public:
TestPacking4();
~TestPacking4();
};
#pragma pack(8)
class DLL_API TestPacking8: public TestPacking
{
public:
TestPacking8();
~TestPacking8();
};
class DLL_API IgnoredType
{

Loading…
Cancel
Save