RLF wrote:
Am upgrading a C++ console app to add a DotNet Front End. Have run into a
couple of issues.
The first one is basically a c++ question. I have a class which maintains a
reference to an istringstream that is passed to it in the constructor.
Since I won't have an istream to give it from the front end, I'd like to add
another ctor that accepts a string and generates the istringstream for me so
that the reference initializer is satisfied.
Haven't found an acceptible way to do that. Could use some help.
You have a lifetime issue here. The existing ctor for your class X stores a
reference to an istringstream object which must outlive the X object, and
you want to add a ctor which creates the istringstream object. One way would
be to add a smart pointer to your class, e.g.
class X
{
public:
X(istringstream& str)
: m_str(str)
{
}
X(const std::string& s)
: m_pStream(new istringstream(s)),
m_str(*m_pStream)
{
}
// Everyone uses m_str
private:
smart_ptr<istringstream> m_pStream;
istringstream& m_str;
};
The second question involves the string itself. I presume the ctor will most
likely need to deal with a System::String coming from the front end. I am
not familiar with the conversions available to turn that into an acceptable
type that can be handled by the istringstream constructor.
Below is a short example which shows how to pass a System::String to the C
function puts. Once you have a pointer to an unmanaged string, you can
convert it to a std::string or whatever unmanaged type you like. See also
PtrToStringChars in the file <vcclr.h>.
#using <mscorlib.dll>
using namespace System;
#include <stdio.h>
void do_puts(String* s)
{
using namespace System::Runtime::InteropServices;
IntPtr p = Marshal::StringToHGlobalAnsi(s);
// Call unmanaged function.
puts(static_cast<const char*>(p.ToPointer()));
Marshal::FreeHGlobal(p);
}
int main()
{
String* s = S"doug";
// puts(s); // Fails - cannot convert from String* to char*
do_puts(s);
return 0;
}
--
Doug Harrison
Microsoft MVP - Visual C++