2013-02-26 2 views
0

В моем приложении необходимо передать абсолютно произвольный объект/структуру в C++-функцию с помощью P/Invoke. Согласно Интернету, любые объекты могут передаваться как структуры C++ (они привязаны к определенной ячейке памяти в течение всего времени вызова). Поскольку меня интересуют только данные и не планируют вызывать какой-либо метод, это соответствует моим потребностям достаточно хорошо. Однако эксперименты показывают, что эти объекты должны иметь атрибут [StructLayout(LayoutKind.Sequential)], иначе код не будет компилироваться. К сожалению, классы создаются другими разработчиками и не гарантируют наличие этого атрибута.Как создать структуру с динамическими свойствами и атрибутами в C#

Чтобы решить эту проблему, одно решение было бы передать объект в специальной C# оберточной функции, которая будет:

  1. получить свойства объекта с помощью Type.GetProperties
  2. Динамически создать на структуру с необходимыми свойствами и скопировать значения из объекта.
  3. Добавить [StructLayout(LayoutKind.Sequential)] атрибут.
  4. Передайте эту структуру в C++ вместе с метаданными извлеченных на шаге 1 (так что C++ знает, что структура объекта и как ее читать)

Как я новичок в C#, я не уверен, как создавать структуры с произвольными свойствами и атрибутами динамически. То, что я нашел до сих пор, - MakeGenericType и ExpandoObject, но необходимо создать динамическую структуру, которая ранее не была определена нигде - даже не как общий объект. Есть идеи?

+0

Вы можете использовать 'VARIANT' на неуправляемой стороне и' object' на управляемой стороне. Не нужно ничего переустанавливать. –

ответ

1

Может ли что-то подобное работать для вас?

[StructLayout(LayoutKind.Sequential)] 
    struct MyStruct 
    { 
     public int Size; 
     public IntPtr PtrToArrayOfMetadata; 
     public IntPtr PtrToArrayOfObjects; 
    } 

    public enum Type 
    { 
     Int, 
     Float, 
     Decimal 
    } 

А потом послать «динамический» объект

 Type[] metadata = new Type[2]; 
     metadata[0] = Type.Int; 
     metadata[1] = Type.Float; 

     object[] obj = new object[2]; 
     obj[0] = 2; 
     obj[1]= 1; 

     GCHandle objHandle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection); 
     IntPtr ptrObj = GCHandle.ToIntPtr(objHandle); 

     objHandle = GCHandle.Alloc(metadata, GCHandleType.WeakTrackResurrection); 
     IntPtr ptrMeta = GCHandle.ToIntPtr(objHandle); 

     MyStruct tmp = new MyStruct(); 
     tmp.Size = 2; 
     tmp.PtrToArrayOfMetadata = ptrMeta; 
     tmp.PtrToArrayOfObjects = ptrObj; 
+0

Смогу ли я передать такую ​​структуру на C++, используя P/Invoke? –

+0

К сожалению, это не моя область знаний. Но, я думаю, вы могли бы. Однако вы должны убедиться, что макет вашей структуры - это то, что вы ожидаете от нее на C++. Невозможно создать какую-либо оболочку для ваших данных? – Evelie

+0

Проблема в том, что я не знаю заранее, какие именно данные. Это может быть любой объект с любыми свойствами. Моя задача состоит в том, чтобы сериализовать эту информацию во что-то, что я могу передать на C++ вместе с метаданными, описывающими ее (так что это не просто капля данных на стороне C). –

Смежные вопросы