Browse Source

Fix the regressed C# marshalling of char*

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

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1350/head
Dimitar Dobrev 6 years ago
parent
commit
6fd9078445
  1. 17
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 7
      tests/CSharp/CSharp.Tests.cs
  3. 5
      tests/CSharp/CSharp.cpp
  4. 1
      tests/CSharp/CSharp.h

17
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -566,10 +566,16 @@ namespace CppSharp.Generators.CSharp
return true; return true;
} }
bool isConst = quals.IsConst || pointer.QualifiedPointee.Qualifiers.IsConst ||
pointer.GetFinalQualifiedPointee().Qualifiers.IsConst;
if (Context.Context.Options.MarshalCharAsManagedChar && if (Context.Context.Options.MarshalCharAsManagedChar &&
primitive == PrimitiveType.Char) primitive == PrimitiveType.Char)
{ {
Context.Return.Write($"({typePrinter.PrintNative(pointer)}) &{param.Name}"); Context.Return.Write($"({typePrinter.PrintNative(pointer)})");
if (isConst)
Context.Return.Write("&");
Context.Return.Write(param.Name);
return true; return true;
} }
@ -577,13 +583,8 @@ namespace CppSharp.Generators.CSharp
if (Context.Parameter.IsIndirect) if (Context.Parameter.IsIndirect)
Context.ArgumentPrefix.Write("&"); Context.ArgumentPrefix.Write("&");
bool isVoid = primitive == PrimitiveType.Void && pointer.IsReference() && isConst;
bool isVoid = primitive == PrimitiveType.Void && if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType || isVoid)
pointee.IsAddress() && pointer.IsReference() &&
(quals.IsConst || pointer.QualifiedPointee.Qualifiers.IsConst ||
pointer.GetFinalQualifiedPointee().Qualifiers.IsConst);
if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType ||
isVoid)
{ {
var local = Generator.GeneratedIdentifier($@"{ var local = Generator.GeneratedIdentifier($@"{
param.Name}{Context.ParameterIndex}"); param.Name}{Context.ParameterIndex}");

7
tests/CSharp/CSharp.Tests.cs

@ -110,6 +110,13 @@ public unsafe class CSharpTests : GeneratorTestFixture
Assert.That(*CSharp.CSharp.TakeConstCharRef(z), Is.EqualTo(z)); Assert.That(*CSharp.CSharp.TakeConstCharRef(z), Is.EqualTo(z));
} }
[Test]
public void TestTakeCharPointer()
{
char c = 'c';
Assert.That(*CSharp.CSharp.TakeCharPointer(&c), Is.EqualTo(c));
}
[Test] [Test]
public void TestIndexer() public void TestIndexer()
{ {

5
tests/CSharp/CSharp.cpp

@ -1645,6 +1645,11 @@ char* returnCharPointer()
return 0; return 0;
} }
char* takeCharPointer(char* c)
{
return c;
}
char* takeConstCharRef(const char& c) char* takeConstCharRef(const char& c)
{ {
return const_cast<char*>(&c); return const_cast<char*>(&c);

1
tests/CSharp/CSharp.h

@ -1362,6 +1362,7 @@ public:
DLL_API void va_listFunction(va_list v); DLL_API void va_listFunction(va_list v);
DLL_API char* returnCharPointer(); DLL_API char* returnCharPointer();
DLL_API char* takeCharPointer(char* c);
DLL_API char* takeConstCharRef(const char& c); DLL_API char* takeConstCharRef(const char& c);
DLL_API const char*& takeConstCharStarRef(const char*& c); DLL_API const char*& takeConstCharStarRef(const char*& c);
DLL_API const void*& rValueReferenceToPointer(void*&& v); DLL_API const void*& rValueReferenceToPointer(void*&& v);

Loading…
Cancel
Save