【问题标题】:How to return a collection of strings from C# to C++ via COM interop如何通过 COM 互操作将字符串集合从 C# 返回到 C++
【发布时间】:2010-11-05 03:31:54
【问题描述】:

我在 C# 中为某些 Display 方法创建了一个 com 组件,它返回一个字符串列表

如下图。在 v++ 中,我使用 std::lst 从 Disp() 捕获返回值,但它

给出 Disp 不是类成员的编译器错误。我将返回类型设为 void 然后

它工作正常。我可以修改什么以便 Disp 返回一个 List 并且在 main(c++) 中我必须使用

这个返回值。

Public interface ITest
{
    List<string> Disp();
}

class TestLib:ITest
{
    List<string> Disp()
    {
        List<string> li=new List<string>();
        li.Add("stack");
        li.Add("over");
        li.Add("Flow");

        return li;
    }
}

成功编译并创建了Test.dll 和test.tlb。 现在在用 c++ 编写的 main 函数中

#include<list>
#import "..\test.tlb"
using namespace Test;
void main()
{
    HRESULT hr=CoInitialize(null);

    ITestPtr Ip(__uuidof(TestLib));

    std::list<string> li=new std::list<string>();

    li=Ip->Disp();
}

当我尝试编译它时,我的代码有什么问题

'Disp':不是 TestLib:ITest 的成员

如何解决这个问题请帮助我....当我在 Class 中将其返回类型为 void 时,它工作正常。我犯了什么错误????

【问题讨论】:

  • 你在 List Disp() 中有错字,“return str”应该是“return li”
  • @Greco - 啊,当我重新格式化代码时,这就是我的烦恼!
  • 嗨,可爱。下次你能不能把你的问题标题写得更清楚一些? :)
  • @Cute - 你试过我在回答中给出的代码吗?我把它放在一个应用程序中并为你测试了它。如果仍然有问题,为什么不尝试并回复?

标签: c# c++ visual-c++ com


【解决方案1】:

即使你改正了错别字,这也是行不通的。 COM 互操作没有从List&lt;T&gt; 到 COM 中的某些内容的标准映射,当然也不会将其映射到 std::list。泛型不允许出现在 COM 接口中。

更新

我尝试使用ArrayList 作为返回类型,因为这是非通用的,我想tlb 可能会包含它的类型信息。那没有用,所以我尝试了IList。这也不起作用(#import 语句生成了一个 .tlh 文件,该文件引用了IList,但没有对其进行定义。)

因此,作为一种解决方法,我尝试声明一个简单的列表接口。代码最终是这样的:

[Guid("7366fe1c-d84f-4241-b27d-8b1b6072af92")]
public interface IStringCollection
{
    int Count { get; }
    string Get(int index);
}

[Guid("8e8df55f-a90c-4a07-bee5-575104105e1d")]
public interface IMyThing
{
    IStringCollection GetListOfStrings();
}

public class StringCollection : List<string>, IStringCollection
{
    public string Get(int index)
    {
        return this[index];
    }
}

public class Class1 : IMyThing
{
    public IStringCollection GetListOfStrings()
    {
        return new StringCollection { "Hello", "World" };
    }
}

所以我有自己的(非常简单的)字符串集合接口。请注意,我的StringCollection 类不必定义Count 属性,因为它从List&lt;string&gt; 继承了一个完美的优点。

然后我在 C++ 端有这个:

#include "stdafx.h"
#import "..\ClassLibrary5.tlb"

#include <vector>
#include <string>

using namespace ClassLibrary5;

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(0);

    IMyThingPtr thing(__uuidof(Class1));

    std::vector<std::string> vectorOfStrings;

    IStringCollectionPtr strings(thing->GetListOfStrings());
    for (int n = 0; n < strings->GetCount(); n++)
    {
        const char *pStr = strings->Get(n);
        vectorOfStrings.push_back(pStr);
    }

    return 0;
}

我必须手动将字符串集合的内容复制到适当的 C++ 标准容器中,但它可以工作。

可能有一种方法可以从标准集合类中获取正确的类型信息,因此您不必制作自己的集合接口,但如果没有,这应该可以正常工作。

另外,您看过 C++/CLI 吗?虽然它仍然不会自动将 CLR 集合转换为标准容器,但它会非常无缝地工作。

【讨论】:

    【解决方案2】:

    好像有好几个错别字。在 C# 中,您声明了一个名为 TestLib 的类,但正在尝试构造一个 TestCls。此外,类和方法都不是公共的(至少在 Disp 上应该是编译错误,因为接口必须公开实现)。

    【讨论】:

      【解决方案3】:

      猜测:Disp() 未声明为 public

      【讨论】:

        猜你喜欢
        • 2010-11-02
        • 1970-01-01
        • 2010-10-15
        • 2010-10-13
        • 2011-11-28
        • 1970-01-01
        • 2015-06-29
        • 2010-10-15
        • 2010-12-27
        相关资源
        最近更新 更多