Browse Source

Added marshaling code for std::ostream using a System.TextWriter to CLI backend.

pull/236/head
Elias Holzer 11 years ago
parent
commit
a72c43fd2f
  1. 79
      include/CppSharp.h
  2. 19
      src/Generator/Types/Std/Stdlib.cs
  3. 17
      tests/STL/STL.Tests.cs
  4. 9
      tests/STL/STL.h

79
include/CppSharp.h

@ -9,7 +9,9 @@ @@ -9,7 +9,9 @@
#pragma once
#include <string>
#include <ostream>
#include <vcclr.h>
#include <msclr/marshal.h>
public interface class ICppInstance
{
@ -212,3 +214,80 @@ namespace clix { @@ -212,3 +214,80 @@ namespace clix {
}
} // namespace clix
// std::ostream marshaling using a System::IO::TextWriter
namespace msclr {
namespace interop {
namespace details {
class text_writer_streambuf : public std::streambuf
{
public:
text_writer_streambuf(const gcroot<System::IO::TextWriter^> & tw)
: std::streambuf()
{
m_tw = tw;
}
~text_writer_streambuf()
{
m_tw->Flush();
}
int_type overflow(int_type ch)
{
if (traits_type::not_eof(ch))
{
auto c = traits_type::to_char_type(ch);
xsputn(&c, 1);
}
return traits_type::not_eof(ch);
}
std::streamsize xsputn(const char *_Ptr, std::streamsize _Count)
{
auto s = gcnew System::String(_Ptr, 0, _Count, System::Text::Encoding::UTF8);
m_tw->Write(s);
return _Count;
}
private:
gcroot<System::IO::TextWriter^> m_tw;
};
class text_writer_ostream : public std::ostream {
public:
text_writer_ostream(const gcroot<System::IO::TextWriter^> & s) :
std::ios(),
std::ostream(0),
m_sbuf(s)
{
init(&m_sbuf);
}
private:
text_writer_streambuf m_sbuf;
};
}
template<>
ref class context_node<std::ostream*, System::IO::TextWriter^> : public context_node_base
{
private:
std::ostream* toPtr;
public:
context_node(std::ostream*& toObject, System::IO::TextWriter^ fromObject)
{
// (Step 4) Initialize toPtr to the appropriate empty value.
toPtr = new details::text_writer_ostream(fromObject);
// (Step 5) Insert conversion logic here.
// (Step 6) Set toObject to the converted parameter.
toObject = toPtr;
}
~context_node()
{
this->!context_node();
}
protected:
!context_node()
{
// (Step 7) Clean up native resources.
delete toPtr;
}
};
}
} // namespace msclr

19
src/Generator/Types/Std/Stdlib.cs

@ -293,4 +293,23 @@ namespace CppSharp.Types.Std @@ -293,4 +293,23 @@ namespace CppSharp.Types.Std
throw new System.NotImplementedException();
}
}
[TypeMap("std::ostream")]
public class OStream : TypeMap
{
public override string CLISignature(CLITypePrinterContext ctx)
{
return "System::IO::TextWriter^";
}
public override void CLIMarshalToNative(MarshalContext ctx)
{
var marshal = ctx.MarshalToNative as CLIMarshalManagedToNativePrinter;
marshal.ArgumentPrefix.Write("*");
var marshalCtxName = string.Format("ctx_{0}", ctx.Parameter.Name);
ctx.SupportBefore.WriteLine("msclr::interop::marshal_context {0};", marshalCtxName);
ctx.Return.Write("{0}.marshal_as<std::ostream*>({1})",
marshalCtxName, ctx.Parameter.Name);
}
}
}

17
tests/STL/STL.Tests.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
using System;
using CppSharp.Utils;
using NUnit.Framework;
using STL;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CppSharp.Utils;
using NUnit.Framework;
using System.Runtime.InteropServices;
using STL;
public class STLTests : GeneratorTestFixture
{
@ -47,5 +47,14 @@ public class STLTests : GeneratorTestFixture @@ -47,5 +47,14 @@ public class STLTests : GeneratorTestFixture
for (int i = 0; i < 3; i++)
Assert.AreEqual(i, valueTypeWrapperList[i].Value);
}
[Test]
public void TestOStream()
{
const string testString = "hello wörld";
var stringWriter = new StringWriter();
OStreamTest.WriteToOStream(stringWriter, testString);
Assert.AreEqual(testString, stringWriter.ToString());
}
}

9
tests/STL/STL.h

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
#include "../Tests.h"
#include <vector>
#include <ostream>
struct DLL_API IntWrapper
{
@ -28,3 +29,11 @@ struct DLL_API TestVectors @@ -28,3 +29,11 @@ struct DLL_API TestVectors
// Should get mapped to List<IntWrapperValueType>
std::vector<IntWrapperValueType> IntWrapperValueTypeVector;
};
struct DLL_API OStreamTest
{
static void WriteToOStream(std::ostream& stream, const char* s)
{
stream << s;
};
};
Loading…
Cancel
Save