加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PInvoke:将文本从C转到C#时出错

发布时间:2020-12-16 07:26:59 所属栏目:百科 来源:网络整理
导读:我使用Pinvoke实现Native(C)代码和Managed(C#)代码之间的互操作性.我想要实现的是从本机代码中获取一些文本作为后续值,即我的C#代码调用我的C函数将一些文本返回给C#.以下是我的代码. C代码: static std::wstring WSTR_TEMP;wchar_t* cppReturnSomeText() {
我使用Pinvoke实现Native(C)代码和Managed(C#)代码之间的互操作性.我想要实现的是从本机代码中获取一些文本作为后续值,即我的C#代码调用我的C函数将一些文本返回给C#.以下是我的代码.

C代码:

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#代码:

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

每件事都按预期工作正常.现在我只需将操作系统从WinXP(32位)更改为Win7(64位).当我运行此代码后发生错误:

“试图读取或写入受保护的内存.这通常表明其他内存已损坏.”

解决方法

我想问题是你用C运行时的分配器分配内存,但C#marshaller试图解除分配它.那不行.您需要使用相同的分配器分配和取消分配.

我知道解决问题的最好方法是用BSTR编组.这使用了很快在本机模块和托管模块之间共享的COM分配器.

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

在C#端你这样做:

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

这样做的另一个好处是您的代码现在是线程安全的,因为您不再需要全局变量.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读