Основная проблема заключается имеет союз двух разных типов структуры. С использованием только основных типов и одного, включая массивы, которые вызывают проблемы. < /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;
Это выглядело так: < /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;
}
Код: Выделить всё
[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)] , чтобы избавиться от этого материала модификации памяти, которые я вкладываю в 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;
}
Код: Выделить всё
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 Любые предложения и комментарии очень приветствуются!
С уважением,
tobias < /p>
Подробнее здесь: https://stackoverflow.com/questions/714 ... or-c-sharp
Мобильная версия