See the question and my original answer on StackOverflow

When you're using Visual Studio and the #import directive, the generated code uses _bstr_t which is a smart wrapper class over BSTR (the raw Windows type).

So, you don't have to use SysAllocString nor SysFreeString, you can just use _bstr_t very naturally. For example, in your case, if your C# method signature is like this:

public string ShowDialog(string stringToPrint) // you don't need the MarshalAs here, the TLB will build it as a BSTR

then you can use a C++ code like this:

... other imports or includes
// import mscorlib so we have a full generated cool code (I recommend not to use raw_interfaces_only)
// we rename 'or' to something that doesn't pose problems. Your mileage can vary depending on your building context...
#import "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb" rename("or","whatever")
#import "C:\myPath\MyClassLibrary1.tlb" // adapt to your path

int main()
    MyClassLibrary1::_Class1Ptr ptr;
    HRESULT hr = ptr.CreateInstance(__uuidof(MyClassLibrary1::Class1)); // should return S_OK/0

    _bstr_t input = L"111111";
    _bstr_t res = ptr->ShowDialog(input); // assign the return string
    wprintf(L"res:%s\n", res.GetBSTR()); // output (unicode) result to console

You could also directly write this:

_bstr_t res = ptr->ShowDialog(L"111111");

// or this (with automatic ansi to unicode conversion)

_bstr_t res = ptr->ShowDialog("111111");

All _bstr_t are automatically allocated and freed.