【问题标题】:How to use COM to pass a string from c# to c++?如何使用 COM 将字符串从 c# 传递到 c++?
【发布时间】:2011-09-09 21:04:30
【问题描述】:

当我尝试从 c++ 调用 c# 代码时,我按照本文中的说明进行操作

http://support.microsoft.com/kb/828736

我的 c# 的一部分是:

[Guid("6A2E9B00-C435-48f8-AEF1-747E9F39E77A")]
public interface IGameHelper
{
 void getInfo(out string result);
}

public class GameHelper : IGameHelper
{
 void getInfo(out string result)
 {
  result =  new StringBuilder().Append("Hello").ToString();
 }

}

我的 C++ 代码的一部分:

#import "../lst/bin/Release/LST.tlb" named_guids raw_interfaces_only
using namespace LST;
using namespace std;

...
HRESULT hr = CoInitialize(NULL);
IGameHelperPtr pIGame(__uuidof(GameHelper));
BSTR ha = SysAllocString(NULL);
pIGame->GetInfo(&ha);
wprintf(_T(" %s"),ha);
SysFreeString(ha);

但我无法获取字符串结果值,当我尝试获取整数结果时它工作正常,但不是字符串。

我不太了解COM。请帮我。 谢谢。

【问题讨论】:

  • wprintf(_T(" %s"),ha);总是打印 并且似乎 BSTR ha 无法获取结果字符串。
  • BSTR ha = SysAllocString(NULL) - 这里不需要,因为结果是 OUT 参数。而是使用 BSTR ha = NULL;
  • 在 C++ 和 C# 之间,使用 C++/CLI 进行互操作可能更简单。然后你可以避免 COM,这总是一件好事。 :)
  • @jalf 感谢您的评论。 CLI 是一个更简单的解决方案,但我真的很想找出正确的 COM 方式。
  • 你能把方法签名从'out string'改成'ref string'吗?

标签: c# visual-studio-2008 visual-c++ com com-interop


【解决方案1】:

According to Msdn 如果你在传入 NULL 时调用 SysAllocString,它会返回 NULL。

您不是因此将对 NULL 指针的引用传递到您的 COM 接口吗?如果是这样,ha 将永远不会被填充? (我不确定 COM,所以可能是错误的)

【讨论】:

  • 是的 Sysallocstring(NULL) 将返回 NULL。但我被告知 COM 服务器应该分配字符串,而 com 客户端应该使用 sysfreestring 释放结果。我试过 BSTR ha = SysAllocString(L"NotJarvis");pIGame->GetInfo(&ha); wprintf(_T("%s"),ha);但它也会打印 NotJarvis。
  • 是的,抱歉 - 我已经有一段时间没有使用 COM - 你是对的。
【解决方案2】:

通常您的代码应该可以工作,但首先要确保它可以正确编译,因为GameHelper 内部的void getInfo(out string result) 应该是公开的。然后再次pIGame->GetInfo(&ha); 应该用getInfo 修复。因此,您可能正在运行旧版本的代码。

【讨论】:

  • 感谢您的宝贵时间。抱歉拼写错误。我已经使用“gacutil /u XXX”然后“gacutil /i XXX.dll”在 gac 中刷新我的 com。并清理并重建 c++ 项目,但它无法正常工作。很奇怪。
  • 也许您还应该检查调用 getInfo 返回的 HRESULT。代码应该可以工作,我自己测试过。
【解决方案3】:

将您的 C# 代码更改为:

[Guid("6A2E9B00-C435-48f8-AEF1-747E9F39E77A")]
public interface IGameHelper
{
    string getInfo();
}


public class GameHelper : IGameHelper
{
    public string getInfo()
    {
       return "Hello World";
    }

}

然后你的 C++ 客户端:

HRESULT hr = CoInitialize(NULL);
IGameHelperPtr pIGame(__uuidof(GameHelper));
_bstr_t ha = pIGame->GetInfo();
wprintf(_T(" %s"),ha);

应该可以的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2012-06-03
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多