Skip to content

Commit f4673f5

Browse files
ddobrevtritao
authored andcommitted
Extended the type maps for primitive strings to C++/CLI.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent b0aa6e1 commit f4673f5

File tree

3 files changed

+71
-53
lines changed

3 files changed

+71
-53
lines changed

src/Generator/Generators/CLI/CLIMarshal.cs

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
6060
// const char* and const char[] are the same so we can use a string
6161
if (array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
6262
array.QualifiedType.Qualifiers.IsConst)
63-
return VisitPointerType(new PointerType
64-
{
65-
QualifiedPointee = array.QualifiedType
66-
}, quals);
63+
{
64+
var pointer = new PointerType { QualifiedPointee = array.QualifiedType };
65+
Context.ReturnType = new QualifiedType(pointer);
66+
return this.VisitPointerType(pointer, quals);
67+
}
6768
goto case ArrayType.ArraySize.Variable;
6869

6970
case ArrayType.ArraySize.Variable:
@@ -100,13 +101,6 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
100101
return true;
101102
}
102103

103-
if (pointer.IsConstCharString())
104-
{
105-
Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
106-
pointer.Pointee.Desugar() as BuiltinType));
107-
return true;
108-
}
109-
110104
PrimitiveType primitive;
111105
var param = Context.Parameter;
112106
if (param != null && (param.IsOut || param.IsInOut) &&
@@ -167,29 +161,6 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
167161
return pointer.QualifiedPointee.Visit(this);
168162
}
169163

170-
private string MarshalStringToManaged(string varName, BuiltinType type)
171-
{
172-
var encoding = type.Type == PrimitiveType.Char ?
173-
Encoding.ASCII : Encoding.Unicode;
174-
175-
if (Equals(encoding, Encoding.ASCII))
176-
encoding = Context.Context.Options.Encoding;
177-
178-
string param;
179-
if (Equals(encoding, Encoding.ASCII))
180-
param = "E_UTF8";
181-
else if (Equals(encoding, Encoding.Unicode) ||
182-
Equals(encoding, Encoding.BigEndianUnicode))
183-
param = "E_UTF16";
184-
else
185-
throw new NotSupportedException(string.Format("{0} is not supported yet.",
186-
Context.Context.Options.Encoding.EncodingName));
187-
188-
return string.Format(
189-
"({0} == 0 ? nullptr : clix::marshalString<clix::{1}>({0}))",
190-
varName, param);
191-
}
192-
193164
public override bool VisitMemberPointerType(MemberPointerType member,
194165
TypeQualifiers quals)
195166
{
@@ -513,18 +484,6 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
513484

514485
var pointee = pointer.Pointee.Desugar();
515486

516-
if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
517-
pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
518-
pointer.QualifiedPointee.Qualifiers.IsConst)
519-
{
520-
Context.Before.WriteLine(
521-
"auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
522-
Context.ArgName, Context.Parameter.Name);
523-
524-
Context.Return.Write("_{0}.c_str()", Context.ArgName);
525-
return true;
526-
}
527-
528487
if (pointee is FunctionType)
529488
{
530489
var cppTypePrinter = new CppTypePrinter();

src/Generator/Generators/CLI/CLITypePrinter.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ public override TypePrinterResult VisitDelegate(FunctionType function)
107107
public override TypePrinterResult VisitPointerType(PointerType pointer,
108108
TypeQualifiers quals)
109109
{
110+
TypeMap typeMap;
111+
if (Context.TypeMaps.FindTypeMap(pointer.Desugar(), out typeMap))
112+
{
113+
var typePrinterContext = new TypePrinterContext
114+
{
115+
Kind = ContextKind,
116+
MarshalKind = MarshalKind,
117+
Type = pointer
118+
};
119+
120+
return typeMap.CLISignatureType(typePrinterContext).Visit(this);
121+
}
122+
110123
var pointee = pointer.Pointee.Desugar();
111124

112125
if (pointee is FunctionType)
@@ -115,9 +128,6 @@ public override TypePrinterResult VisitPointerType(PointerType pointer,
115128
return string.Format("{0}^", function.Visit(this, quals));
116129
}
117130

118-
if (pointer.IsConstCharString())
119-
return "System::String^";
120-
121131
// From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
122132
// Any of the following types may be a pointer type:
123133
// * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.

src/Generator/Types/Std/Stdlib.cs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,58 @@ public override Type CSharpSignatureType(TypePrinterContext ctx)
9090
}
9191
}
9292

93-
[TypeMap("const char*", GeneratorKind = GeneratorKind.CSharp)]
93+
[TypeMap("const char*")]
9494
public class ConstCharPointer : TypeMap
9595
{
96+
public override Type CLISignatureType(TypePrinterContext ctx)
97+
{
98+
return new CILType(typeof(string));
99+
}
100+
101+
public override void CLIMarshalToNative(MarshalContext ctx)
102+
{
103+
ctx.Before.WriteLine(
104+
"auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
105+
ctx.ArgName, ctx.Parameter.Name);
106+
107+
ctx.Return.Write("_{0}.c_str()", ctx.ArgName);
108+
}
109+
110+
public override void CLIMarshalToManaged(MarshalContext ctx)
111+
{
112+
if (ctx.Parameter != null && !ctx.Parameter.IsOut &&
113+
!ctx.Parameter.IsInOut)
114+
{
115+
ctx.Return.Write(ctx.Parameter.Name);
116+
return;
117+
}
118+
119+
Type type = ctx.ReturnType.Type.Desugar();
120+
Type pointee = type.GetPointee().Desugar();
121+
var isChar = type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
122+
(pointee.IsPointerToPrimitiveType(PrimitiveType.Char) &&
123+
ctx.Parameter != null &&
124+
(ctx.Parameter.IsInOut || ctx.Parameter.IsOut));
125+
var encoding = isChar ? Encoding.ASCII : Encoding.Unicode;
126+
127+
if (Equals(encoding, Encoding.ASCII))
128+
encoding = Context.Options.Encoding;
129+
130+
string param;
131+
if (Equals(encoding, Encoding.ASCII))
132+
param = "E_UTF8";
133+
else if (Equals(encoding, Encoding.Unicode) ||
134+
Equals(encoding, Encoding.BigEndianUnicode))
135+
param = "E_UTF16";
136+
else
137+
throw new System.NotSupportedException(
138+
$"{Context.Options.Encoding.EncodingName} is not supported yet.");
139+
140+
ctx.Return.Write(
141+
$@"({ctx.ReturnVarName} == 0 ? nullptr : clix::marshalString<clix::{
142+
param}>({ctx.ReturnVarName}))");
143+
}
144+
96145
public override Type CSharpSignatureType(TypePrinterContext ctx)
97146
{
98147
if (ctx.Kind == TypePrinterContextKind.Managed)
@@ -178,17 +227,17 @@ public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
178227
}
179228
}
180229

181-
[TypeMap("const char[]", GeneratorKind = GeneratorKind.CSharp)]
230+
[TypeMap("const char[]")]
182231
public class ConstCharArray : ConstCharPointer
183232
{
184233
}
185234

186-
[TypeMap("const wchar_t*", GeneratorKind = GeneratorKind.CSharp)]
235+
[TypeMap("const wchar_t*")]
187236
public class ConstWCharTPointer : ConstCharPointer
188237
{
189238
}
190239

191-
[TypeMap("const char16_t*", GeneratorKind = GeneratorKind.CSharp)]
240+
[TypeMap("const char16_t*")]
192241
public class ConstChar16TPointer : ConstCharPointer
193242
{
194243
}

0 commit comments

Comments
 (0)