首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C#中使用C++组件对象模型

在C#中使用C++组件对象模型
EN

Stack Overflow用户
提问于 2012-09-03 21:38:47
回答 2查看 1.5K关注 0票数 5

我正在尝试使用C#项目在C++中构建一个COM库来进行测试。有些方法需要向调用者返回字符串。在从C#调用这些方法时,我得到了这样的结果:“在位置读取访问冲突...”

这是我的测试项目中的C++代码(不包括VS2010ATL生成的所有内容)

代码语言:javascript
运行
复制
//COMTest.idl
[id(1)] HRESULT Test([out,retval] BSTR* ret);

//Program2.h
STDMETHOD(Test)(BSTR* ret);

//Program2.cpp
STDMETHODIMP CProgram2::Test(BSTR* ret)
{
   BSTR tmp = (BSTR)CoTaskMemAlloc(sizeof(wchar_t) * 2);
   tmp[0] = L'H';
   tmp[1] = L'\0';

   *ret = (BSTR)tmp;
   return S_OK;
}

在C#中,我只是从COM-Tab中引用了DLL,关闭了"Embed Interop Types“,因为它会导致错误,并运行以下代码:

代码语言:javascript
运行
复制
static void Main(string[] args)
{
   COMTestLib.Program2Class instance = new COMTestLib.Program2Class();
   string tmp = instance.Test(); //Where the error occurs

   Console.WriteLine(tmp); //This is not reached

   Console.Read();
}

离开Test-Method后出现错误。我从我的C#项目中调试了C++代码,值被放在了正确的位置。如果我尝试返回0(在C#中为null ),即使我仍然像示例中那样分配内存,也不会得到错误。

我无法理解访问冲突所抱怨的地址。它既不是我正在分配的地址,也不是该方法中使用的任何其他地址。我还觉得奇怪的是,CoTaskMemAlloc-Function总是返回第一个字节设置为0 (0x00XXXXXX)的地址,但这可能只是COM的问题。

我的想法用完了,我在任何地方都找不到太多关于这方面的信息(除了基本的COM教程)。有人能帮上忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-04 03:54:31

BSTR需要额外的内存(以跟踪字符串len),因此必须使用SysAllocString()函数来分配BSTR(或者使用一个“智能”BSTR类)。

所以你的原始代码应该是这样的:

代码语言:javascript
运行
复制
//Program2.cpp
STDMETHODIMP CProgram2::Test(BSTR* ret)
{
   *ret = SysAllocString(L"H");
   return S_OK;
}

关于BSTR的一本好书:http://blogs.msdn.com/b/ericlippert/archive/2003/09/12/52976.aspx

票数 4
EN

Stack Overflow用户

发布于 2012-09-03 22:09:21

检查您的COM项目和测试项目是否都是STA。也检查一下bitness。如果用LPSTR替换BSTR会怎么样?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12249007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档