将托管的 C# 列表返回到非托管的 C++ 代码

3

我有一个C# dll(已设置为注册COM互操作选项)。

这个C# dll有以下接口和类:

interface IMyInterface
{
    bool IsNameExists(string name);
    List<string> GetNameList();
} 

public class MyClass : IMyInterface
{

    public bool IsNameExists(string name)
    {
        //DO Something

    }
    public List<string> GetNameList()
    {

        // DO something
    }

} 

我需要从非托管的C++中调用IsNameExists和GetNameList方法。
#import "..\..\ProdCon\bin\ProdCon.tlb" raw_interfaces_only

   void main()
   {    
        HRESULT hr =::CoInitialize(NULL);
        IMyInterface pIMyInterface(__uuidof(MyClass));

        VARIANT_BOOL bRet = FALSE;

        BSTR bstrName = ::SysAllocString(_T("RAJESH"));
        hr =  pIMyInterface->IsNameExists(bstrName,&bRet);

    }

我创建了以上的COM对象,并且成功地调用了IsNameExists方法。

由于GetNameList方法返回列表,我收到以下警告:

'MyDll.IMyInterface.GetNameList(#0), MyDll'. 警告:类型库导出器在签名中遇到了一个泛型类型实例。通用代码可能无法导出到COM。

请帮助我如何将C#列表返回给非托管的C++代码,以便非托管的C++代码可以使用这个列表。


COM对.NET泛型一无所知。请返回ArrayList或非泛型IEnumerator或您自己的集合接口。 - Hans Passant
1个回答

1
'通用代码可能无法导出到COM。' => 因此,在 public List GetNameList() 中,它是类型参数字符串。因此,您需要访问非泛型的c#方法来获取数据。
如果您控制 MyClass 代码库,则可以(例如)添加:
public string[] GetNameArray()
{
   return GetNameList.ToArray();
}

如果不是这样,那么您需要编写一个代理/包装类来执行类似于上述操作,并通过COM将其公开,可以使用反射作为一次性或“通用”方法。
例如,请参见http://weblog.west-wind.com/posts/2007/Jul/10/Generics-and-COM-Interop-dont-mix

请问您能帮我解决如何从非托管的C++中访问string[]吗? - srajeshnkl
不确定问题,如果您可以更改MyClass和IMyInterface,那么我建议添加上述方法作为选项,然后您可以像调用IsNameExists一样调用它。 - tolanj
我可以在C#中添加上述的GetNameArray()方法。我想知道如何从C++中检索string[]。 - srajeshnkl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接