Маршалинг комплекса C Страц с C -профсоюзами для C#C#

Место общения программистов C#
Ответить
Anonymous
 Маршалинг комплекса C Страц с C -профсоюзами для C#

Сообщение Anonymous »

Я отчаянно пытаюсь получить комплексный данных C, правильно маршал для C#. Я уже читал все остальные посты относительно этой темы, и у меня заканчиваются идеи, хотя мне кажется, что я очень близок к решению. < /P>
Основная проблема заключается имеет союз двух разных типов структуры. С использованием только основных типов и одного, включая массивы, которые вызывают проблемы. < /P>
Я создал пример для демонстрации ситуации. Структура, беспокойство меня, называется DataStreamConfiguration . Код C выглядит так, рассматриваемая структура находится в нижней части примера C кода: < /p>

Код: Выделить всё

#include "stdint.h"
#include "stddef.h"

typedef enum viewCapEnum {
X = 0,
}viewCapEnum;

typedef struct fraction{
uint8_t nominator;
uint8_t denominator;
}fraction;

typedef struct comSize{
fraction A;
fraction B;
}comSize;

typedef enum someEnum{
A = 0,
B,
C,
D
}someEnum;

typedef struct someSize{
fraction X;
fraction Y;
}someSize;

typedef struct featTemplateCap{
someEnum A;
someSize Size;
}featTemplateCap;

typedef struct featTypeCap{
someEnum AB;
someSize CD;
}featTypeCap;

typedef struct viewCap{
uint8_t A;
uint8_t B;
size_t  BCount;
viewCapEnum ViewCapEnum[50];
comSize MinComSize;
size_t CapaCount;
featTemplateCap TemplCap[14];
size_t TypeCapaCount;
featTypeCap FeatTypeCapa[14];
uint8_t GCount;
}viewCap;

typedef struct featX{
uint16_t A;
uint16_t B;
int16_t  C;
int16_t  D;
}featX;

typedef struct pathCap{
uint8_t Count;
uint8_t Size;
featX   Feat;
}pathCap;

typedef struct dataStreamConfiguration{
size_t FeatureSelector;
union {
viewCap  AsViewCap;
pathCap  AsPathCap;
}dataStream;
}dataStreamConfiguration;
Маршалирование данных данных между C и C# World работает почти для всех, кроме этой DataStreamConfiguration struct. Таким образом, я получил следующий код, где вместо сопоставления (каким -то образом) союз с C# оба дата были помещены один за другим. Так ясно, что это работало неправильно. < /P>
Это выглядело так: < /p>

Код: Выделить всё

public unsafe struct UInt32Struct {
public UInt32 value;
}

public unsafe struct fraction{
public Byte nominator;
public Byte denominator;
}

public unsafe struct comSize{
public fraction A;
public fraction B;
}

public unsafe struct someSize{
public fraction X;
public fraction Y;
}

public unsafe struct featTemplateCap{
public UInt32 A;
public someSize Size;
}

public unsafe struct featTypeCap{
public UInt32   AB;
public someSize CD;
}

public unsafe struct viewCap {
public Byte A;
public Byte B;
public UInt16 BCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50]
public UInt32Struct[] ViewCapEnum;
public comSize MinComSize;
public UInt16 CapaCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14]
public featTemplateCap[] TemplCap;
public UInt16 TypeCapaCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14]
public featTypeCap FeatTypeCapa[14];
public Byte GCount;
}

public unsafe struct featX {
public UInt16 A;
public UInt16 B;
public Int16  C;
public Int16  D;
}

public unsafe struct pathCap {
public Byte Count;
public Byte Size;
public featX Feat;
}

public unsafe struct dataStreamConfiguration {
public UInt16 FeatureSelector;
public viewCap AsViewCap;
public pathCap AsPathCap;
}
Итак, чтобы довести союз в C#, я наткнулся на Layoutkind.explicit и сделал следующее:

Код: Выделить всё

[StructLayout(LayoutKind.Explicit)]
public unsafe struct dataStreamConfiguration {
[FieldOffset(0)]
public UInt16 FeatureSelector;
[FieldOffset(2)]
public viewCap AsViewCap;
[FieldOffset(2)]
public pathCap AsPathCap;
}
< /code>
Это не работало из-за выравнивания типов объектов, которые неверно выровнены или перекрываются полями без объектов. Я много гуглил. Отрегулировал выравнивание до 4 с помощью [structlayout (layoutkind.explice, pack = 4)] 
. Тем не менее, 4,8,16,32, какое бы вы ни было выравнивание, я получил такую ​​же ошибку во время выполнения - неправильно выровнен или перекрыл проблему. О - было развернуть все массивы в C# DataType для всех массивов в ViewCap struct. Как я читал, это может вызвать проблемы выравнивания. Ну, это не сработало. И я обнаружил, что память была изменена, поэтому я не мог найти значения, которые я видел в C, появляющихся сейчас в C#. Большинство значений в C# - 0. OK.
, чтобы избавиться от этого материала модификации памяти, которые я вкладываю в C# на все другие структуры [structlayout (layoutkind.segencient)] Чтобы сохранить порядок элементов, поскольку они находятся в C. К сожалению, это не очень помогло, я также не мог найти значения C-структуры в C#. Тем не менее, это наконец -то работало, когда я избавился от союза и удалил либо Asviewcap , либо Aspathcap (мой слабый момент слепой ярости). ОК, но это не было решением. >

Код: Выделить всё

public unsafe struct dataStreamConfigurationPtr {
public UInt16 FeatureSelector;
public void* Ptr;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct dataStreamConfiguration {
public UInt16 FeatureSelector;
public viewCap AsViewCap;
public pathCap AsPathCap;
}
Вместо того, чтобы иметь перекрывающуюся память со structlayout.explice Я использовал void*, чтобы указывать на неуправляемое местоположение памяти. Для этого я использовал старое определение структуры, чтобы получить память, и вместо этого был союз, я взял первую версию, в которой оба типа разложены друг на друга. Идея состояла в том, чтобы использовать его так: < /p>

Код: Выделить всё

MyFunction(dataStreamConfigurationPtr X, int Status) {

//Create obj and  appropriate space for data
dataStreamConfiguration DataStream = new dataStreamConfiguration();
DataStream.FeatureSelector = X.FeatureSelector;

unsafe{
IntPtr Ptr = new IntPtr(&X.Ptr);
DataStream.AsViewCap = Marshal.PtrToStructure(Ptr);
DataSteram.AsPathCap = Marshal.PtrToStructure
(Ptr);
}

WCFCallback(DataStream, Status);
}
< /code>
Теперь INTPTR указывает на правильную память, однако это работает только для первого элемента структур. Таким образом, для ViewCap 
первого элемента A имеет свои правильные данные, тогда как элемент B, bcount, .. все остальные элементы, кажется, имеют по крайней мере смещенные значения или случайные значения .. Я вполне отчаянно, что делать Теперь я чувствую, что так близок к решению, но понятия не имею, как получить другие данные структуры от C до C#.
Любые предложения и комментарии очень приветствуются!
С уважением,
tobias < /p>

Подробнее здесь: https://stackoverflow.com/questions/714 ... or-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»