在COM中从c#返回对象数组到C
本文关键字:数组 对象 返回 COM 中从 | 更新日期: 2023-09-27 18:11:32
我使用COM在c++和c#之间进行通信。
我在c#中有以下类
-
电子邮件地址
/// <summary> /// Email Address /// </summary> public class EmailAddress { /// <summary> /// SMTP Address /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Address; /// <summary> /// Name /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Name; }
邮箱 /// <summary> /// MailBox Entity /// </summary> public struct MailBoxEntity { /// <summary> /// SMTP Address /// </summary> [MarshalAs(UnmanagedType.BStr)] public string SMTPAddress; /// <summary> /// Mailbox Display Name /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Name; /// <summary> /// Mailbox Server Name /// </summary> [MarshalAs(UnmanagedType.BStr)] public string sServerName; }
EmailEntity(尚未实现IEmailEntity,它将包含每个字段的属性)
/// <summary> /// Class for Email Entity /// </summary> public class EmailEntity : IEmailEntity { /// <summary> /// BccRecipients /// </summary> [MarshalAs(UnmanagedType.ByValArray)] public EmailAddress[] BccRecipients; /// <summary> /// Body /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Body; /// <summary> /// CcRecipients /// </summary> [MarshalAs(UnmanagedType.ByValArray)] public EmailAddress[] CcRecipients; /// <summary> /// Culture /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Culture; /// <summary> /// DateTimeCreated /// </summary> [MarshalAs(UnmanagedType.BStr)] public string DateTimeCreated; /// <summary> /// DateTimeReceived /// </summary> [MarshalAs(UnmanagedType.BStr)] public string DateTimeReceived; /// <summary> /// DateTimeSent /// </summary> [MarshalAs(UnmanagedType.BStr)] public string DateTimeSent; /// <summary> /// FromAddress /// </summary> [MarshalAs(UnmanagedType.BStr)] public string FromAddress; /// <summary> /// FromName /// </summary> [MarshalAs(UnmanagedType.BStr)] public string FromName; /// <summary> /// HasAttachments /// </summary> [MarshalAs(UnmanagedType.BStr)] public string HasAttachments; /// <summary> /// Id /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Id; /// <summary> /// Importance /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Importance; /// <summary> /// LastModifiedName /// </summary> [MarshalAs(UnmanagedType.BStr)] public string LastModifiedName; /// <summary> /// LastModifiedTime /// </summary> [MarshalAs(UnmanagedType.BStr)] public string LastModifiedTime; /// <summary> /// MimeContent /// </summary> [MarshalAs(UnmanagedType.BStr)] public string MimeContent; /// <summary> /// ParentFolderId /// </summary> [MarshalAs(UnmanagedType.BStr)] public string ParentFolderId; /// <summary> /// Original Mailbox /// </summary> [MarshalAs(UnmanagedType.BStr)] public MailBoxEntity OriginalMailBox; /// <summary> /// ParentFolderName /// </summary> [MarshalAs(UnmanagedType.BStr)] public string ParentFolderName; /// <summary> /// ReceivedByAddress /// </summary> [MarshalAs(UnmanagedType.BStr)] public string ReceivedByAddress; /// <summary> /// ReceivedByName /// </summary> [MarshalAs(UnmanagedType.BStr)] public string ReceivedByName; /// <summary> /// Size /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Size; /// <summary> /// Subject /// </summary> [MarshalAs(UnmanagedType.BStr)] public string Subject; /// <summary> /// ToRecipients /// </summary> [MarshalAs(UnmanagedType.ByValArray)] public EmailAddress[] ToRecipients; }
我如何访问访问一个数组的EmailEnity对象(在c++中)返回从一个函数在c#读取EmailEntity类的字段。请注意,EmailEntity类包含如下成员EmailAddress[]本身是一个对象数组。我计划实现接口IEmailEntity,它包含访问EmailEntity字段的属性并使用它来访问c++中的字段。这是正确的方式吗?
如何在c++中访问复杂的字段成员,如EmailAddress (EmailAddress[] toreceivers)数组。
请建议。
谢谢
你可以这样简化。net代码(删除所有应该自动完成的MarshalAs):
[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++程序中实现c# DLL COM文件
然后,你可以在c++中访问这些类,像这样:#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();
}