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.
精彩评论