Я искал несколько дней и до сих пор не нашел правильного ответа. Я нашел this похожий вопрос, который может двигаться в правильном направлении. Я работаю на C#, используя VS2008, и мне нужно общаться с приложением VB6. Моя проблема заключается в том, что у меня есть несколько классов типа конфигурации, которые мне нужно выставить через COM, чтобы доступ к данным содержал приложение VB6. Я отлично справлялся с этим, пока один из моих классов не должен был выставлять параметр массива класса. Моя C# код что-то вроде этого:Как выставить параметр массива класса COM с помощью Interopservices?
[Guid("..."),InterfaceType(ComInterface.InterfaceIsDual)]
public interface iClientComInterop
{
[DispID(1) Properties GetData();
}
[Guid("..."), ClassInterfaceAttribute(ClassInterfaceType.None),ProgIdAttribute("ClientComInterop"),ComDefaultInterfaceAttribute(typeof(iClientComInterop))]
public class ClientComInterop : iClientComInterop
{
public ClientComInterop()
{
}
public Properties GetData()
{...}
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("...")]
public interface iProperties
{
[DispId(1)]
int Id{get; }
[DispId(2)]
ProcessingInformation ProcessingInfo { get; }
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ConfigurationTypes.Properties")]
[Guid("...")]
public class Properties : iProperties
{
public int Id
{
get ;
set ;
}
public ProcessingInformation ProcessingInfo
{
get ;
set ;
}
public Properties()
{
...
}
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("...")]
public interface iProcessingInformation
{
[DispId(1)]
bool Enabled {get; }
[DispId(2)]
AccountInformation[] accounts { [return:MarshalAs(UnmanagedType.SafeArray)]get; }
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ConfigurationTypes.ProcessingInformation")]
[Guid("...")]
public class ProcessingInformation : iProcessingInformation
{
public bool Enabled
{
get ;
set ;
}
public AccountInformation[] Accounts
{
get;
set;
}
public ProcessingInformation()
{
...
}
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("...")]
public interface iAccountInformation
{
[DispId(1)]
int Type {get; }
[DispId(2)]
double balance{ get; }
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ConfigurationTypes.AccountInformation")]
[Guid("...")]
public class AccountInformation: iAccountInformation
{
public int Type
{
get ;
set ;
}
public double balance
{
get;
set;
}
public AccountInformation()
{
...
}
}
Это все компилируется, регистры и отображается в обозревателе объектов VB6 ищет правильно, но я не смог получить массив AccountInformation из ProcessingInformation. Я получаю ошибку несоответствия объекта. Эти данные необходимо получить как часть объекта Properties с помощью функции GetData(). Я совершенно не понимаю, как я должен это делать. Я могу вытащить любую другую информацию из Properties и ProcessingInformation, но не информацию в массиве AccountInformation.
VB6 Пример:
Public Client As ClientComInterop.ClientComInteropSet
Client = CreateObject("ClientComInterop")
Dim data as ConfigurationTypes.PropertiesSet
data = Client.GetData()
Print "ID: " ; data.ID ' This works
Print "Process enabled: "; data.ProcessingInfo.Enabled ' This works
Print "Accounts Type: "; data.ProcessingInfo.Accounts(0).Type ' error Type mismatch
Я пытаюсь несколько других вещей, а также, например, создание локального массива счетов и попытался установить это с data.ProcessingInfo.Accounts. Это тоже не сработало, я получаю ту же ошибку «Тип несоответствия».
Что мне не хватает?
Спасибо за но это не устраняет проблему. Я теперь не получаю «несоответствие типа ошибки», но я не могу увидеть массив или даже идентифицировать учетные записи как массив в коде VB6, с вышеуказанным заявлением на печать. Ошибка времени выполнения: «Неверное количество аргументов или недопустимое присвоение свойств». Если я создам массив типа Variant в моем коде VB6 и попытаюсь установить это с данными из data.ProcessingInfo.Accounts, я все равно получаю ошибку несоответствия типа. – TaterTot
@TaterTot, см. Мое обновление. – Noseratio
@ Norseratio, Спасибо за ваши дальнейшие усилия. Извините, я так долго возвращался к этому. К сожалению, это не похоже на решение в этом случае. Единственный способ, который я нашел, который позволит мне получить доступ к любой из фактических данных в массиве, - это изменить интерфейс класса на ProcessingInformation от None до AutoDual. Это не лучший случай для меня, он позволяет получить доступ к другому элементу в ProcessingInformation, которые не являются частью интерфейса. – TaterTot