Browse Source

Generated valid code for wrapping char arrays.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/256/merge
Dimitar Dobrev 10 years ago
parent
commit
a18479e1db
  1. 4
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 10
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 4
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  4. 6
      src/Generator/Generators/CLI/CLITypePrinter.cs
  5. 23
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  6. 9
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  7. 6
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  8. 6
      tests/Common/Common.Tests.cs
  9. 4
      tests/Common/Common.cpp
  10. 9
      tests/Common/Common.h

4
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -561,7 +561,9 @@ namespace CppSharp.Generators.CLI
WriteLine("{0} get();", type); WriteLine("{0} get();", type);
if (!variable.QualifiedType.Qualifiers.IsConst) var arrayType = type as ArrayType;
var qualifiedType = arrayType != null ? arrayType.QualifiedType : variable.QualifiedType;
if (!qualifiedType.Qualifiers.IsConst)
WriteLine("void set({0});", type); WriteLine("void set({0});", type);
WriteCloseBraceIndent(); WriteCloseBraceIndent();

10
src/Generator/Generators/CLI/CLIMarshal.cs

@ -59,6 +59,16 @@ namespace CppSharp.Generators.CLI
supportBefore.WriteCloseBraceIndent(); supportBefore.WriteCloseBraceIndent();
Context.Return.Write(value); Context.Return.Write(value);
break; break;
case ArrayType.ArraySize.Incomplete:
// const char* and const char[] are the same so we can use a string
if (array.Type.IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return VisitPointerType(new PointerType
{
QualifiedPointee = array.QualifiedType
}, quals);
goto case ArrayType.ArraySize.Variable;
case ArrayType.ArraySize.Variable: case ArrayType.ArraySize.Variable:
Context.Return.Write("nullptr"); Context.Return.Write("nullptr");
break; break;

4
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -623,7 +623,9 @@ namespace CppSharp.Generators.CLI
{ {
GeneratePropertyGetter(variable, @class, variable.Name, variable.Type); GeneratePropertyGetter(variable, @class, variable.Name, variable.Type);
if (!variable.QualifiedType.Qualifiers.IsConst) var arrayType = variable.Type as ArrayType;
var qualifiedType = arrayType != null ? arrayType.QualifiedType : variable.QualifiedType;
if (!qualifiedType.Qualifiers.IsConst)
GeneratePropertySetter(variable, @class, variable.Name, variable.Type); GeneratePropertySetter(variable, @class, variable.Name, variable.Type);
} }

6
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -63,6 +63,12 @@ namespace CppSharp.Generators.CLI
public string VisitArrayType(ArrayType array, TypeQualifiers quals) public string VisitArrayType(ArrayType array, TypeQualifiers quals)
{ {
// const char* and const char[] are the same so we can use a string
if (array.SizeType == ArrayType.ArraySize.Incomplete &&
array.Type.IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return "System::String^";
return string.Format("cli::array<{0}>^", array.Type.Visit(this)); return string.Format("cli::array<{0}>^", array.Type.Visit(this));
} }

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

@ -91,7 +91,6 @@ namespace CppSharp.Generators.CSharp
if (!VisitType(array, quals)) if (!VisitType(array, quals))
return false; return false;
Class @class;
switch (array.SizeType) switch (array.SizeType)
{ {
case ArrayType.ArraySize.Constant: case ArrayType.ArraySize.Constant:
@ -105,14 +104,28 @@ namespace CppSharp.Generators.CSharp
if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void)) if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void))
supportBefore.WriteLineIndent("{0}[i] = new global::System.IntPtr({1}[i]);", supportBefore.WriteLineIndent("{0}[i] = new global::System.IntPtr({1}[i]);",
value, Context.ReturnVarName); value, Context.ReturnVarName);
else if (array.Type.Desugar().TryGetClass(out @class) && @class.IsRefType)
supportBefore.WriteLineIndent("{0}[i] = {1}.{2}(*(({1}.Internal*)&({3}[i * sizeof({1}.Internal)])));",
value, array.Type, Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
else else
supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName); {
Class @class;
if (array.Type.Desugar().TryGetClass(out @class) && @class.IsRefType)
supportBefore.WriteLineIndent("{0}[i] = {1}.{2}(*(({1}.Internal*)&({3}[i * sizeof({1}.Internal)])));",
value, array.Type, Helpers.CreateInstanceIdentifier, Context.ReturnVarName);
else
supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName);
}
supportBefore.WriteCloseBraceIndent(); supportBefore.WriteCloseBraceIndent();
Context.Return.Write(value); Context.Return.Write(value);
break; break;
case ArrayType.ArraySize.Incomplete:
// const char* and const char[] are the same so we can use a string
if (array.Type.IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return VisitPointerType(new PointerType
{
QualifiedPointee = array.QualifiedType
}, quals);
goto case ArrayType.ArraySize.Variable;
case ArrayType.ArraySize.Variable: case ArrayType.ArraySize.Variable:
Context.Return.Write("null"); Context.Return.Write("null");
break; break;

9
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -1017,9 +1017,14 @@ namespace CppSharp.Generators.CSharp
var location = string.Format("CppSharp.SymbolResolver.ResolveSymbol(\"{0}\", \"{1}\")", var location = string.Format("CppSharp.SymbolResolver.ResolveSymbol(\"{0}\", \"{1}\")",
libSymbol.Item1, libSymbol.Item2); libSymbol.Item1, libSymbol.Item2);
var isRefTypeArray = decl.Type is ArrayType && @class != null && @class.IsRefType; var arrayType = decl.Type as ArrayType;
var isRefTypeArray = arrayType != null && @class != null && @class.IsRefType;
if (isRefTypeArray) if (isRefTypeArray)
WriteLine("var {0} = (byte*){1};", Generator.GeneratedIdentifier("ptr"), location); WriteLine("var {0} = {1}{2};", Generator.GeneratedIdentifier("ptr"),
arrayType.Type.IsPrimitiveType(PrimitiveType.Char) &&
arrayType.QualifiedType.Qualifiers.IsConst
? string.Empty : "(byte*)",
location);
else else
WriteLine("var {0} = ({1}*){2};", Generator.GeneratedIdentifier("ptr"), WriteLine("var {0} = ({1}*){2};", Generator.GeneratedIdentifier("ptr"),
@var.Type, location); @var.Type, location);

6
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -153,6 +153,12 @@ namespace CppSharp.Generators.CSharp
}; };
} }
// const char* and const char[] are the same so we can use a string
if (array.SizeType == ArrayType.ArraySize.Incomplete &&
array.Type.IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return "string";
return string.Format("{0}[]", array.Type.Visit(this)); return string.Format("{0}[]", array.Type.Visit(this));
// C# only supports fixed arrays in unsafe sections // C# only supports fixed arrays in unsafe sections

6
tests/Common/Common.Tests.cs

@ -565,6 +565,12 @@ public class CommonTests : GeneratorTestFixture
} }
} }
[Test]
public void TestIncompleteCharArray()
{
Assert.That(Foo.charArray, Is.EqualTo("abc"));
}
private class CustomDerivedFromVirtual : AbstractWithVirtualDtor private class CustomDerivedFromVirtual : AbstractWithVirtualDtor
{ {
public override void @abstract() public override void @abstract()

4
tests/Common/Common.cpp

@ -14,11 +14,9 @@ Foo::Foo(Private p)
{ {
} }
const int Foo::unsafe;
const char* Foo::GetANSI() const char* Foo::GetANSI()
{ {
return "ANSI"; return "ANSI";
} }
void Foo::TakesTypedefedPtr(FooPtr date) void Foo::TakesTypedefedPtr(FooPtr date)

9
tests/Common/Common.h

@ -45,9 +45,10 @@ public:
IgnoredType ignoredType; IgnoredType ignoredType;
int fixedArray[3]; int fixedArray[3];
void* ptr; void* ptr;
static const int unsafe = 10; static const int unsafe;
static const char charArray[];
const char* GetANSI(); const char* GetANSI();
// Not properly handled yet - ignore // Not properly handled yet - ignore
float nested_array[2][2]; float nested_array[2][2];
@ -62,6 +63,10 @@ public:
bool operator ==(const Foo& other) const; bool operator ==(const Foo& other) const;
}; };
// HACK: do not move these to the cpp - C++/CLI is buggy and cannot link static fields initialised in the cpp
const int Foo::unsafe = 10;
const char Foo::charArray[] = "abc";
struct DLL_API Bar struct DLL_API Bar
{ {
enum Item enum Item

Loading…
Cancel
Save