且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从C#中的COM对象返回数组到C

更新时间:2023-02-09 14:49:13

你可以简化.NET代码是这样的(除去应该自动完成所有的MarshalAs):

You could simplify the .NET Code like this (remove all MarshalAs that should be done automatically):

[ComVisible(true)]
public class MyRootClass : IMyRootClass // some class to start with
{
    public IEmailEntity[] GetEntities()
    {
        List<IEmailEntity> list = new List<IEmailEntity>();
        for(int i = 0; i < 10; i++)
        {
            EmailEntity entity = new EmailEntity();
            List<IEmailAddress> addresses = new List<IEmailAddress>();
            addresses.Add(new EmailAddress { Name = "Joe" + i });
            entity.BccRecipients = addresses.ToArray();
            entity.Body = "hello world " + i;
            list.Add(entity);
        }
        return list.ToArray();
    }   
}

[ComVisible(true)]
public interface IMyRootClass
{
    IEmailEntity[] GetEntities();
}

public class EmailEntity : IEmailEntity
{
    public IEmailAddress[] BccRecipients { get; set; }
    public string Body { get; set; }
}

public class EmailAddress : IEmailAddress
{
    public string Address { get; set; }
    public string Name { get; set; }
}

[ComVisible(true)]
public interface IEmailAddress
{
    string Address { get; set; }
    string Name { get; set; }
}

[ComVisible(true)]
public interface IEmailEntity
{
    IEmailAddress[] BccRecipients { get; set; }
    string Body { get; set; }
    // to be continued...
}

要使用它使用C ++,你需要注册DLL,并建立一个.TLB(类型库文件)作为在这里了类似的回答解释:的实施一个C#DLL COM文件在非托管C ++程序

To use it with C++, you need to register the DLL and build a .TLB (Type Library file) as explained in a similar answer here: Implement a C# DLL COM File In Unmanaged C++ Program

然后,您可以访问这些类C ++的,是这样的:

Then, you can access these classes in C++, like this:

#include "stdafx.h"
#import  "c:\MyPathToTheTlb\YourAssembly.tlb" // import the COM TLB

using namespace YourAssembly;

int _tmain(int argc, _TCHAR* argv[])
{
  CoInitialize(NULL);
  IMyRootClassPtr ptr(__uuidof(MyRootClass));
  CComSafeArray<IUnknown*> entities = ptr->GetEntities(); // CComSafeArray needs atlsafe.h in the PCH
  for(int i = entities.GetLowerBound(0); i <= entities.GetUpperBound(0); i++)
  {
    IEmailEntityPtr entity;
    entities.GetAt(i).QueryInterface(&entity);
    _bstr_t body = entity->Body;
    printf("%S\n", body.GetBSTR());

    CComSafeArray<IUnknown*> recipients = entity->BccRecipients;
    for(int j = recipients.GetLowerBound(0); j <= recipients.GetUpperBound(0); j++)
    {
      IEmailAddressPtr address;
      recipients.GetAt(j).QueryInterface(&address);
      _bstr_t name = address->Name;
      printf(" %S\n", name.GetBSTR());
    }
  }
  CoUninitialize();
}