Click here to Skip to main content
15,883,957 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi everyone,

I am writing a library using C++ and want to make it portable and accessable in other languages (like .NET languages). This is why I decided to wrap the library inside an COM DLL, using ATL.

Now my problem is that I am unable to pass ANSI strings from the library through the RCW back to the client. My code looks something like this:
MIDL
// IDL:
[propget, helpstring("String")] HRESULT String([out, retval] LPSTR* plpszValue);

// Implementation of the method:
STDMETHODIMP CMyClass::get_String(LPSTR* plpszValue)
{
	std::string sStdStr("Test");	// Create std string
	*plpszValue = _strdup(sStdStr.c_str());	// Copy std string and pass pointer to the copy back to the caller.

	return S_OK;
}
Now accessing the code looks like this:
C#
// C# code
MyClass oClass = new MyClass();
Console.WriteLine(oClass.String);	// Throws System.Interop.COMException
However passing strings into the other direction (client -> server, means propput) works fine. Also returning an empty or predefined string does not throw an exception:
C++
// Implementation of the method:
STDMETHODIMP CMyClass::get_String(LPSTR* plpszValue)
{
    std::string sStdStr("Test");    // Create std string
    *plpszValue = "Test";

    return S_OK;
}
This is why I think the problem is related into _strdup(). So can anyone tell me what I did wrong? What's wrong with my idea of allocating memory for a string and returning it's pointer to the client?

I hope you can help, thank you!

P.S.: My project is built with Multi-Byte-Characterset (ANSI), not Unicode.
Posted
Updated 16-Apr-11 23:57pm
v5

1 solution

Usually COM is using BSTR for marshalled strings. Allocated by SysAllocString and freed by SysFreeString.
Regards.
 
Share this answer
 
Comments
Aschratt 17-Apr-11 6:33am    
I used BSTR's before, but they do not support 8-byte-charsets. I've build my library on top of a file format using ANSI strings and I hoped to change the charset of my library to ANSI, too, to get rid of validation code.
mbue 17-Apr-11 8:23am    
Some COM functions are using CoTaskMemAlloc resp. CoTaskMemFree to allocate strings.
Regards.
Aschratt 17-Apr-11 9:15am    
Great one!

This solved my problem. I wrote a function to emulate _strdup() behavior with COM memory allocation:
static LPSTR _CoStrDup(LPCSTR lpszStr)
{
// Allocate memory for the string and the terminator.
SIZE_T nSize = strlen(lpszStr) + 1;
LPSTR lpszStrAlloc = (LPSTR)CoTaskMemAlloc(nSize);
strcpy_s(lpszStrAlloc, nSize, lpszStr);
return lpszStrAlloc;
}

Thanks again!
Sergey Alexandrovich Kryukov 17-Apr-11 16:17pm    
My 5.
--SA

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