我想在C ++中创建一个C#类对象并设置其成员字段。 虽然我能够创建一个C ++类对象,但我无法访问它的成员并设置成员字段值。
/// <summary>
/// Class for AQS Entity
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
[Guid("70F12A44-B91D-474D-BD70-32B1ACE041D6")]
[ProgId("AQSEntity")]
public class AQSEntity : IEntity
{
public AQSEntity()
{
sRecoveryDBName = String.Empty;
arrSourceMailboxesEntity = null;
sQueryString = String.Empty;
}
[MarshalAs(UnmanagedType.BStr)]
public string sRecoveryDBName = string.Empty;
[MarshalAs(UnmanagedType.ByValArray)]
public MailBoxCollection arrSourceMailboxesEntity;
[MarshalAs(UnmanagedType.BStr)]
public string sQueryString;
}
并且IEntity类定义如下
[Guid("5C71057E-9FD9-47D5-B022-8D5F9C7007D3")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IEntity
{
}
在C ++中,
IEntity* pTest1 = NULL;
hr = CoCreateInstance(__uuidof(**AQSEntity**),NULL,CLSCTX_INPROC_SERVER,__uuidof(IEntity),(void**)&pTest1);
我想在C ++中访问AQSEntity类的成员。但是我无法访问它们。
pTest1-&GT; sQueryString
给出错误。
'sQueryString':不是。的成员 'AsigraExchange :: IEntity'C:\ PROJECTS \ COM \ COMClient \ COMClient.cpp 168
任何人都可以建议我错在哪里。
谢谢, GAGAN
答案 0 :(得分:2)
一切都表现得如此:)
在您的C ++项目中,您可以访问IEntity
接口上声明的所有方法,这些方法都没有。
您的实施,即AQSEntity
课程,应实施所有IEntity
成员。现在在该类中声明的方法是类的成员,它们与IEntity
无关。
这意味着您需要在IEntity
接口中声明所有必需的方法,然后在AQSEntity
中实现它们。请注意,您还要公开类的字段,而不是方法。您将必须定义方法(或属性,它们将转换为C ++方面的方法),然后实现它们。类似的东西:
public interface IEntity
{
public string RecoveryDBName { get; }
}
您还必须在界面中指定[MarshalAs]
属性,尽管UnmanagedType.BStr
是字符串的默认属性,因此您可以省略它们。
编辑:
根据评论,似乎IEntity
只是一个标记界面,不打算作为API公开(属性可能是更好的选项,因为IEntity
不会在客户端上使用无论如何)。
在这种情况下,有两种选择:
1)更好的方法,虽然它需要更多的工作:从IAQSEntity
派生IEntity
接口,在其上声明方法,并在AQSEntity
类上实现
2)工作量减少,但更脆弱:将AQSEntity
标记为ClassInterfaceType.AutoDual
而不是ClassInterfaceType.None
- 这会将成员公开给COM客户端,但版本会更难以及还将公开基类型成员。
以下是我要选择的内容:
[ClassInterface(ClassInterfaceType.None)]
...
[Entity] // instead of IEntity marker interface
public class AQSEntity : IAQSEntity
{
public string RecoveryDbName { get; }
}
[Guid("...")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAQSEntity // no base interface IEntity!
{
string RecoveryDbName { get; }
}
使用Entity
属性而不是IEntity
标记接口的唯一缺点是,如果要将接口用作泛型的约束
答案 1 :(得分:0)
您的界面确实不包含任何成员。您需要将成员放入界面,然后在您的类中实现该界面。