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