如何通过COM互操作将字符串集合从C#返回到C ++

时间:2009-06-23 11:46:29

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

我为C#中的某些Display方法创建了一个com componet,它返回一个String List

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

给出编译器错误,即Disp不是类的成员。我将返回类型设为无效

它工作正常。什么我可以修改,以便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

如何解决这个问题PLZ帮助我....当我在类中返回类型为void它工作正常。我做错了什么????

3 个答案:

答案 0 :(得分:7)

即使你修正了错别字,这也行不通。 COM interop没有从List<T>到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<string>继承了完美的优点。

然后我在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集合转换为std容器。

答案 1 :(得分:1)

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

答案 2 :(得分:-2)

猜猜:Disp()未声明为公开