Отказ от ответственности: почти ноль с концепциями маршаллинга.
У меня есть структура B, которая содержит строку + массив структур C. Мне нужно отправить это через гигантскую пропасть взаимодействия потребителю COM - C++. Какой набор атрибутов мне нужен, чтобы украсить определение структуры?
[ComVisible (true)]
[StructLayout(LayoutKind.Sequential)]
public struct A
{
public string strA
public B b;
}
[ComVisible (true)]
[StructLayout(LayoutKind.Sequential)]
public struct B
{
public int Count;
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct, SizeParamIndex=0)]
public C [] c;
}
[ComVisible (true)]
[StructLayout(LayoutKind.Sequential)]
public struct C
{
public string strVar;
}
редактировать: @Andrew В основном это проблема моих друзей. У него есть эта штука, работающая в .Net - он выполняет некоторую автоматическую магию, чтобы создать .tlb / .tlh, который затем можно использовать в области C++. Проблема в том, что он не может исправить размер массива.





Ответ зависит от того, какие родные определения вы тоже пытаетесь маршалировать. Вы не предоставили достаточно информации, чтобы кто-то мог действительно помочь.
Обычная вещь, которая сбивает людей с толку при маршалинге строк в собственных массивах, заключается в том, что собственные массивы часто используют буфер фиксированного размера для строки, которая выделяется внутри структуры. Ваше определение упорядочивает строки как указатель на другой блок памяти, содержащий строку (по умолчанию).
[MarshalAs (UnmanagedType.ByValTStr, SizeConst = ##)] может быть тем, что вы ищете ...
C++: самый мощный язык программирования .NET Framework
Я собирался подойти к проекту, который должен был упорядочить структурированные данные через границу C++ / C#, но я нашел способ лучше (особенно если вы знаете C++ и любите изучать новые языки программирования). Если у вас есть доступ к Visual Studio 2005 или более поздней версии, вы можете подумать об использовании C++ / CLI вместо маршалинга. Это в основном позволяет вам создать эту волшебную гибридную библиотеку .NET / native классов, которая на 100% совместима с C# (как если бы вы написали все на C# для целей использования в другом проекте C#), которая также на 100% совместима с C и / или C++. В вашем случае вы можете написать оболочку C++ / CLI, которая маршалирует данные из C++ в памяти в CLI в типах памяти.
Мне очень повезло с этим, используя чистый код C++ для чтения и записи файлов данных (это может быть даже какая-то сторонняя библиотека), а затем мой код C++ / CLI преобразует (копирует) данные C++ в Типы .NET в памяти, которые можно использовать напрямую, как если бы я написал библиотеку чтения / записи на C#. Для меня единственным препятствием был синтаксис, поскольку вам нужно изучить расширения CLI для C++. Хотел бы я, чтобы у меня был StackOverflow, чтобы задавать вопросы по синтаксису, когда я изучал это!
Взамен на изучение синтаксиса вы, вероятно, изучаете самый мощный язык программирования, который только можно вообразить. Подумайте об этом: элегантность и разумность библиотек C# и .NET, а также низкоуровневая совместимость с собственными библиотеками C++. Вы бы не хотели писать все свои проекты на C++ / CLI, но он отлично подходит для переноса данных C++ в проекты C# /. NET. Это «просто работает».
Руководство:
Я не согласен. вся магия C++ / cli - это вызов методов System.Runtime.InteropServices.Marshal за кулисами с гораздо большими накладными расходами. и ваш проект, вероятно, будет несовместим со следующей версией VS ..