Browse Source

Merge pull request #306 from tomspilman/str_inout

Const String In/Out Support
pull/308/head
João Matos 11 years ago
parent
commit
43ce59a5b1
  1. 18
      src/Generator/Generators/CLI/CLIMarshal.cs
  2. 5
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  3. 3
      src/Generator/Generators/CLI/CLITypePrinter.cs
  4. 17
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  5. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  6. 18
      tests/Basic/Basic.Tests.cs
  7. 27
      tests/Basic/Basic.cpp
  8. 5
      tests/Basic/Basic.h

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

@ -67,15 +67,6 @@ namespace CppSharp.Generators.CLI
var pointee = pointer.Pointee.Desugar(); var pointee = pointer.Pointee.Desugar();
PrimitiveType primitive;
var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut) &&
pointee.IsPrimitiveType(out primitive))
{
Context.Return.Write(Context.ReturnVarName);
return true;
}
if (pointee.IsPrimitiveType(PrimitiveType.Void)) if (pointee.IsPrimitiveType(PrimitiveType.Void))
{ {
Context.Return.Write(Context.ReturnVarName); Context.Return.Write(Context.ReturnVarName);
@ -89,6 +80,15 @@ namespace CppSharp.Generators.CLI
return true; return true;
} }
PrimitiveType primitive;
var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut) &&
pointee.IsPrimitiveType(out primitive))
{
Context.Return.Write(Context.ReturnVarName);
return true;
}
if (pointee.IsPrimitiveType(out primitive)) if (pointee.IsPrimitiveType(out primitive))
{ {
var returnVarName = Context.ReturnVarName; var returnVarName = Context.ReturnVarName;

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

@ -1101,7 +1101,12 @@ namespace CppSharp.Generators.CLI
var type = paramType.Visit(typePrinter); var type = paramType.Visit(typePrinter);
if (param.IsInOut) if (param.IsInOut)
{
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore);
WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return); WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return);
}
else else
WriteLine("{0} {1};", type, argName); WriteLine("{0} {1};", type, argName);
} }

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

@ -155,8 +155,7 @@ namespace CppSharp.Generators.CLI
{ {
// Skip one indirection if passed by reference // Skip one indirection if passed by reference
var param = Context.Parameter; var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut) if (param != null && (param.IsOut || param.IsInOut))
&& pointee == finalPointee)
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
return pointee.Visit(this, quals) + "*"; return pointee.Visit(this, quals) + "*";

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

@ -430,8 +430,21 @@ namespace CppSharp.Generators.CSharp
pointee.IsPrimitiveType(PrimitiveType.WideChar)) && pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
pointer.QualifiedPointee.Qualifiers.IsConst) pointer.QualifiedPointee.Qualifiers.IsConst)
{ {
Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name)); if (Context.Parameter.IsOut)
CSharpContext.Cleanup.WriteLine("Marshal.FreeHGlobal({0});", Context.ArgName); {
Context.Return.Write("IntPtr.Zero");
CSharpContext.ArgumentPrefix.Write("&");
}
else if (Context.Parameter.IsInOut)
{
Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
CSharpContext.ArgumentPrefix.Write("&");
}
else
{
Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
CSharpContext.Cleanup.WriteLine("Marshal.FreeHGlobal({0});", Context.ArgName);
}
return true; return true;
} }

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

@ -217,8 +217,7 @@ namespace CppSharp.Generators.CSharp
{ {
// Skip one indirection if passed by reference // Skip one indirection if passed by reference
var param = Context.Parameter; var param = Context.Parameter;
if (isManagedContext && param != null && (param.IsOut || param.IsInOut) if (isManagedContext && param != null && (param.IsOut || param.IsInOut))
&& pointee == finalPointee)
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate) if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate)

18
tests/Basic/Basic.Tests.cs

@ -57,6 +57,24 @@ public class BasicTests : GeneratorTestFixture
Assert.That(hello.RetEnum(Enum.F), Is.EqualTo(-9)); Assert.That(hello.RetEnum(Enum.F), Is.EqualTo(-9));
} }
[Test]
public void TestPrimitiveConstCharStringInOut()
{
var hello = new Hello();
string str;
hello.StringOut(out str);
Assert.That(str, Is.EqualTo("HelloStringOut"));
hello.StringOutRef(out str);
Assert.That(str, Is.EqualTo("HelloStringOutRef"));
str = "Hello";
hello.StringInOut(ref str);
Assert.That(str, Is.EqualTo("StringInOut"));
str = "Hello";
hello.StringInOutRef(ref str);
Assert.That(str, Is.EqualTo("StringInOutRef"));
}
[Test] [Test]
public void TestPrimitiveOutParameters() public void TestPrimitiveOutParameters()
{ {

27
tests/Basic/Basic.cpp

@ -1,4 +1,5 @@
#include "Basic.h" #include "Basic.h"
#include <string.h>
Foo::Foo() Foo::Foo()
{ {
@ -203,6 +204,32 @@ void Hello::EnumInOutRef(CS_IN_OUT Enum& e)
e = Enum::F; e = Enum::F;
} }
void Hello::StringOut(CS_OUT const char** str)
{
*str = "HelloStringOut";
}
void Hello::StringOutRef(CS_OUT const char*& str)
{
str = "HelloStringOutRef";
}
void Hello::StringInOut(CS_IN_OUT const char** str)
{
if (strcmp(*str, "Hello") == 0)
*str = "StringInOut";
else
*str = "Failed";
}
void Hello::StringInOutRef(CS_IN_OUT const char*& str)
{
if (strcmp(str, "Hello") == 0)
str = "StringInOutRef";
else
str = "Failed";
}
int unsafeFunction(const Bar& ret, char* testForString, void (*foo)(int)) int unsafeFunction(const Bar& ret, char* testForString, void (*foo)(int))
{ {
return ret.A; return ret.A;

5
tests/Basic/Basic.h

@ -132,6 +132,11 @@ public:
void EnumInOut(CS_IN_OUT Enum* e); void EnumInOut(CS_IN_OUT Enum* e);
void EnumInOutRef(CS_IN_OUT Enum& e); void EnumInOutRef(CS_IN_OUT Enum& e);
void StringOut(CS_OUT const char** str);
void StringOutRef(CS_OUT const char*& str);
void StringInOut(CS_IN_OUT const char** str);
void StringInOutRef(CS_IN_OUT const char*& str);
}; };
class DLL_API AbstractFoo class DLL_API AbstractFoo

Loading…
Cancel
Save