Click here to Skip to main content
15,912,756 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have a .NET component which accepts a string object. I have a VC++ application which calls this function.

So when I pass a BSTR object to .NET component function which accepts a string, the string is empty inside the component.

How should we do this conversion i.e passing a BSTR object to .NET string object?
Posted

Hello,

Example from C++ side:
interface declaration
C++
interface ISampleInterface:public IUnknown
{
    STDMETHOD(put_Value)(BSTR _value) = 0;
    STDMETHOD(get_Value)(BSTR * _value) = 0;
};

Class example which provide that functionality:
C++
class CTest : public ISampleInterface
{
	// skipped IUnknown
private:
	WCHAR m_szString[1024];
public:
	CTest() {wcscpy_s(m_szString,L"");}
public:
	STDMETHODIMP put_Value(BSTR _value);
	{
		if (!_value || !wcslen(_value)) return E_INVALIDARG;
		wcscpy_s(m_szString,_value);
		return NOERROR;
	}
        STDMETHODIMP get_Value(BSTR * _value)
	{
		if (!_value) return E_INVALIDARG;
		*_value = SysAllocString(m_szString);
		return NOERROR;
	}
};

Example on C# side with specify marshaling type:
Here is type specified so .NET will do marshaling stuff in RCW.
C#
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISampleInterface
{
    [PreserveSig]
    int put_Value([In, MarshalAs(UnmanagedType.BStr)] string _value);

    [PreserveSig]
    int get_Value([Out, MarshalAs(UnmanagedType.BStr)] out string _value);
}

Example on C# side without marshaling:
Here you directly perform marshaling type.
C#
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISampleInterface
{
    [PreserveSig]
    int put_Value(IntPtr _value);

    [PreserveSig]
    int get_Value(out IntPtr _value);
}

For such declaration you should have code:
C#
// initialized somewhere
ISampleInterface _sample;
// Put value
{
    IntPtr _ptr = Marshal.StringToBSTR("some string");
    _sample.put_Value(_ptr);
    Marshal.FreeBSTR(_ptr);
}
// Get value
{
    IntPtr _ptr;
    _sample.get_Value(out _ptr);
    string _result = Marshal.PtrToStringBSTR(_ptr);
    Marshal.FreeBSTR(_ptr);
}


Regards,
Maxim.
 
Share this answer
 
v2
Comments
skydger 18-Oct-12 3:18am    
Nice solution. It's not just convertion strings answer, but a complete guide to work with COM xD. My 5.
Maxim Kartavenkov 18-Oct-12 5:35am    
Thanks
Hello! I presume, that you have put_StringData(BSTR str ) in your component, so for std::string you could use this code:
C++
std::string std_string = "Some string data";
_bstr_t some_string = std_string.c_str();

mycomponent->put_StringData(some_string.GetBSTR());


or for CString te following
C++
CString cstr_string = "Some string data";
_bstr_t some_string(cstr_string);

mycomponent->put_StringData(some_string.GetBSTR());
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900