Предоставление вложенных массивов COM из .NET
-
09-06-2019 - |
Вопрос
У меня есть метод в .NET (С#), который возвращает string[][]
.При использовании RegAsm или TlbExp (из .NET 2.0 SDK) для создания библиотеки типов COM для содержащей сборки я получаю следующее предупреждение:
ПРЕДУПРЕЖДЕНИЕ:Для вложенных массивов не поддерживается маршалинг.
Это предупреждение приводит к тому, что рассматриваемый метод не экспортируется в созданную библиотеку типов.Мне сказали, что есть способы обойти это, используя Variant в качестве типа возвращаемого значения COM, а затем приведя / и т. д. на стороне COM-клиента.Для данной конкретной сборки целевая клиентская аудитория — VB6. Но как на самом деле это сделать на стороне .NET?
Примечание:У меня есть существующая устаревшая DLL (с ее экспортированной библиотекой типов), в которой тип возвращаемого значения — Variant, но эта DLL (и .tlb) создается с использованием устаревших инструментов, предшествующих .NET, поэтому я не могу их использовать.
Помогло бы вообще, если бы сборка была написана на VB.NET?
Решение
Даже если вы вернете объект (который сопоставляется с вариантом в COM-взаимодействии), это не решит вашу проблему.VB сможет «держать» его и «передавать», но ничего с ним сделать не сможет.
Технически в VB нет точного эквивалента для строки[][].Однако если ваш массив не является «зубчатым» (то есть все подмассивы имеют одинаковую длину), вы сможете использовать двумерный массив в качестве возвращаемого типа.COM Interop должен иметь возможность это перевести.
string [,] myReturnValue = new string[rowCount,colCount];
Возвращает ли ваш метод формально объект (который будет выглядеть как вариант для VB) или строку[,] (которая будет выглядеть как массив строк в VB), несколько несущественно.Массив String является более приятным возвратом, но не является обязательным требованием.
Если вы массив является зазубренный, то вам придется придумать другой метод.Например, вы можете сделать возвращаемый 2D-массив размером с самый большой из подмассивов, а затем передать информацию о длине в отдельном параметре [out] int[], чтобы VB мог знать, какие элементы используются.
Другие советы
Эквивалентом варианта в C# является System.Object.Поэтому вы можете попытаться вернуть результат приведения к объекту и как вариант забрать его на другой стороне.
В VB нет никаких возможностей, которых нет в C#, поэтому я сомневаюсь, что было бы лучше или проще, если бы часть .NET была написана на VB.