locked
Converting managed string to unmanaged string RRS feed

  • Question

  • Hi,

    i dlike to use RegisterWindowMessage func. and SendMessage func. to sending any string (for example string str = "Hello World") from managed(C#) process to another unmanaged process( Win32 nat. app., C++). Message is catched correctly., but MessageBox didnt display "Hello World":

    MessageBox(hwnd, (LPCSTR)wParam, (LPCSTR)lParam, MB_OK);

    My question sound: How can i display string(text) from C# under Win32App project.

    Thanks for yours time. 

    Saturday, April 2, 2011 11:18 AM

Answers

  • In your C# program, call Marshal.StringToBSTR(s).ToPointer() and pass this value as LPARAM.

     

    In your C++ program, convert LPARAM to BSTR and use the string. If you want to display it without conversions, then try MessageBoxW instead of MessageBox.

     

    Call Marshal.FreeBSTR after SendMessage, unless the string is owned by C++ program.

     

    • Marked as answer by Johny Cage Sunday, April 3, 2011 12:18 PM
    Saturday, April 2, 2011 4:03 PM

All replies

  • i always use these two function i hope it might help

    String * EuOpProxyObject::ConvertToManagedString(std::wstring &str)
        {
            IntPtr ptr(static_cast<System::IntPtr>(static_cast<void*>(const_cast<wchar_t *>(str.c_str()))));
            return System::Runtime::InteropServices::Marshal::PtrToStringUni(ptr);        
    //        System::Runtime::InteropServices::Marshal::FreeCoTaskMem(ptr);
        }

     

        const wchar_t * EuOpProxyObject::ConvertToStdString(String *str)
        {
            IntPtr ptr(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(str));
            return  static_cast<const wchar_t *>(static_cast<void *>(ptr));       
        }


    Fahd Anwar
    Saturday, April 2, 2011 11:30 AM
  • You can use the marshal_as facility to convert from a managed String
    to some form of native string (such as std:string).

    string stdStr = marshal_as<string>( YourManagedStringVariable );

    See the MSDN documentation on using marshal_as.

    Dave

    Saturday, April 2, 2011 1:54 PM
  • In your C# program, call Marshal.StringToBSTR(s).ToPointer() and pass this value as LPARAM.

     

    In your C++ program, convert LPARAM to BSTR and use the string. If you want to display it without conversions, then try MessageBoxW instead of MessageBox.

     

    Call Marshal.FreeBSTR after SendMessage, unless the string is owned by C++ program.

     

    • Marked as answer by Johny Cage Sunday, April 3, 2011 12:18 PM
    Saturday, April 2, 2011 4:03 PM
  • On 02/04/2011 15:54, David Lowndes [MVP] wrote:

    You can use the marshal_as facility to convert from a managed String
    to some form of native string (such as std:string).

    string stdStr = marshal_as<string>( YourManagedStringVariable );

    In addition to what David wrote, please note that C# strings are Unicode strings, instead std::string's are ANSI. So the conversion is "lossy".

    Converting from C# strings to std::wstring (Unicode UTF-16 strings) could be better.

    Giovanni

    Saturday, April 2, 2011 4:21 PM
  • Also consider an alternative that can work: the WM_COPYDATA message. It allows you to send data (like strings) between processes. In your C# program create an array of bytes (MemoryStream and String.ToCharArray can help) containing the strings. For example you can insert zero-terminated strings. Then use unsafe and fixed keyword to obtain a pointer to array of bytes and send it using WM_COPYDATA. There are many samples about WM_COPYDATA in C#.

     

    In C++ program, extract the strings from received data.

     

    If you want to pass more kinds of messages, then include into WM_COPYDATA a code of the message.

     

     

     

    Saturday, April 2, 2011 5:35 PM
  • You can use the marshal_as facility to convert from a managed String
    to some form of native string (such as std:string).

    string stdStr = marshal_as<string>( YourManagedStringVariable );

    In addition to what David wrote, please note that C# strings are Unicode strings, instead std::string's are ANSI. So the conversion is "lossy".

    Converting from C# strings to std::wstring (Unicode UTF-16 strings) could be better.

    Quite right, and the code is then just:

    wstring stdStr = marshal_as<wstring>( YourManagedStringVariable );

    The marshal_as facility is quite neat and efficient except for the
    conversion the other way, in which case I've found code is faster to
    execute if you just do this:

    String^ ManagedString = gcnew String( native string pointer (const
    char *) or (const wchar_t *) )

    Dave

    Saturday, April 2, 2011 9:48 PM
  •     const wchar_t * EuOpProxyObject::ConvertToStdString(String *str)
        {
            IntPtr ptr(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(str));
            return  static_cast<const wchar_t *>(static_cast<void *>(ptr));       
        }


    Fahd Anwar


    That looks buggy to me. You are returning a dangling pointer.

     

    Sunday, April 3, 2011 12:19 AM
  • Hi Brian,

    I am also facing same issue but this solution is not working for me.

    ==== My code=======

    --------c# code -----------------

    public unsafe IntPtr Testing()
            {
                string string_aux = "Stringtochange";
                void* pt = Marshal.StringToBSTR(string_aux).ToPointer();
                IntPtr ab = new IntPtr(pt);
                return ab;
            }

    public void GetValue()

    {

    SendMessageW(utilityHandle1, Win32Utilities.RegisterWindowMessage("GetControlFRomROT"), handle,iTesting());

    }

    ---------------------------c++---------------

    wchar_t st = (wchar_t)lParam;

    std::wstring abc;

    LPCTSTR str = abc.c_str(); 

    MessageBox(NULL,str,L"stringvalue",NULL);

    =================

    Here in messagebox it showing some junk value.

    can you tell me how to convert LPARAM value CString in c++ with correct value.

    Regards,

    Rajendar.

    Tuesday, October 20, 2015 10:51 AM