开发者

PInvoke: Error in returing text from C++ to C#

I am using Pinvoke for Interoperability between Native(C++) code and Managed(C#) code. What i want to achieve is get some text from native code into my managed code as a retrun value i.e My C# Code calls my C++ func开发者_如何学运维tion which returns some text back to C#. Following is my code for this.

C++ Code:

static std::wstring WSTR_TEMP;
wchar_t* cppReturnSomeText()
 {
     UnicodeString usText ("Some Text Here");
     WSTR_TEMP = ECUtilsICU::UniCodeStringToWString(usText);
     return  (wchar_t *)(WSTR_TEMP.c_str());
 }

C# Code:

[DllImport(MY_DLL_NAME]
[return: MarshalAs(UnmanagedType.LPWStr)]
private static extern string cppReturnSomeText();
public static string GetSomeText()
{
string s = cppReturnSomeText();
return s;
}

Every thing was working fine as expected. Now i simply change my operating system from WinXP(32Bit) to Win7(64Bit). And when i run this code following error occurred:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."


I guess the problem is that you are allocating memory with your C++ runtime's allocator but then the C# marshaller attempts to deallocate it. That cannot work. You need to allocate and deallocate with the same allocator.

The best way I know to solve your problem is to marshal with a BSTR. That uses the COM allocator which is happy to be shared between native and managed modules.

#include <comutil.h>
BSTR cppReturnSomeText()
{
    UnicodeString usText("Some Text Here");
    std::wstring result = ECUtilsICU::UniCodeStringToWString(usText);
    return ::SysAllocString(result.c_str());
}

On the C# side you do this:

[DllImport(MY_DLL_NAME, CallingConvention=CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string cppReturnSomeText();

One other benefit of this is that your code is now thread-safe because you no longer need a global variable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜