从C#中的COM对象返回数组到C [英] return array of object from C# to C in COM

查看:118
本文介绍了从C#中的COM对象返回数组到C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用COM C ++和C#之间进行通信。

I am using COM to communicate between C++ and C#.

我在C#中的以下类


  1. 电子邮件地址

  1. Email Address

/// <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;
}


  • 邮箱

  • Mailbox

    /// <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其中将包含每个字段属性)

  • EmailEntity (yet to implement IEmailEntity which will contain properties for each field)

    /// <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的[],它本身就是对象的数组。
    我正打算实施包含的属性来访问EmailEntity
    的领域,并用它来访问字段C ++接口IEmailEntity。那是正确的方法是什么?

    How do I access access an array of EmailEnity objects (in C++) returned from a function in C# and read the fields of the EmailEntity class. Please note that EmailEntity class contains members like EmailAddress[] which itself is an array of objects. I was planning to implement interface IEmailEntity that contains properties to access fields of EmailEntity and use it to access fields in C++. Is that the right way ?

    如何访问复杂的领域成员类似于C ++ EmailAddress的数组(EmailAddress的[] ToRecipients)。

    How do I access complex fields members like array of EmailAddress (EmailAddress[] ToRecipients) in C++.

    请建议。

    感谢

    推荐答案

    你可以简化.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();
    }
    

    这篇关于从C#中的COM对象返回数组到C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆