如何将其转换为 C#(编组)
我有这些声明 (DLL) 并尝试将其转换为 C#,以便我可以从 DLL 调用函数。
struct1 到 struct3 相同
typedef struct1
{
int num;
char chars[25];
short shrt;
union
{
struct4 objstruct4;
}
}
typedef struct
{
Long Length;
short Type;
union
{
struct1 objStruct1;
struct2 objStruct2;
struct3 objStruct3;
}Data;
} Msg;
在 C# 中,我将这些转换...struct1 到 struct3 相同
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct struct1
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
[MarshalAs(UnmanagedType.I2)]
public short shrt;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct struct4
{
[MarshalAs(UnmanagedType.Struct)]
public ...
...
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
protected struct Msg
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.I4)]
public int Length;
[FieldOffset(4)]
[MarshalAs(UnmanagedType.I2)]
public short Type;
[FieldOffset(6)]
[MarshalAs(UnmanagedType.Struct)]
public Data MsgData;
}
[StructLayout(LayoutKind.Explicit, Pack = 1, CharSet = CharSet.Ansi)]
public struct Data
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct1 objStruct1;
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct2 objStruct2;
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct3 objStruct3;
}
问题是当我尝试从 DLL 调用函数并将 struct MSG 作为 REF 传递时, 内部结构/联合(struct1 到 struct3)的某些成员变量没有值。 就像它们在内存中隆隆作响......
但是当我删除 struct MSG 中的 struct1 或 struct2 时,剩余内部结构/联合内的所有成员变量都被成功检索。
请问我的转换是否正确或者我错过了什么吗? 或者是否有更好的方法来转换此问题,或者您已经找到了出现此问题的原因。 我怀疑的一件事是结构体(ANSI 或 Unicode)的大小,以及变量、结构体的排列。
请指教 - 谢谢。
样本2:
////////////////////////////////
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct1
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct2
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num2;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct3
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
[MarshalAs(UnmanagedType.I4)]
public Int32 num3;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct4
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num4;
[MarshalAs(UnmanagedType.Struct)]
public Data DataMsg;
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct Data
{
//[FieldOffSet(0)]
public struct1 str1;
//[FieldOffSet(0)]
public struct2 str2;
//[FieldOffSet(0)]
public struct3 str3;
}
}
////////////////
I have these declarations (DLL) and tried to convert it in C# so i can call the functions from the DLL.
Same for struct1 to struct3
typedef struct1
{
int num;
char chars[25];
short shrt;
union
{
struct4 objstruct4;
}
}
typedef struct
{
Long Length;
short Type;
union
{
struct1 objStruct1;
struct2 objStruct2;
struct3 objStruct3;
}Data;
} Msg;
In C#, i converted these...same for struct1 to struct3
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct struct1
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
[MarshalAs(UnmanagedType.I2)]
public short shrt;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct struct4
{
[MarshalAs(UnmanagedType.Struct)]
public ...
...
}
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
protected struct Msg
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.I4)]
public int Length;
[FieldOffset(4)]
[MarshalAs(UnmanagedType.I2)]
public short Type;
[FieldOffset(6)]
[MarshalAs(UnmanagedType.Struct)]
public Data MsgData;
}
[StructLayout(LayoutKind.Explicit, Pack = 1, CharSet = CharSet.Ansi)]
public struct Data
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct1 objStruct1;
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct2 objStruct2;
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public struct3 objStruct3;
}
Problem is when I tried to call a function from the DLL and passed the struct MSG as REF,
some member variables of the inner structs/union (struct1 to struct3) don't have values.
Its like they are rumbled inside the memory...
But when I remove the struct1 or struct2 in struct MSG, all of the member variables inside the remaining inner structs/union were successfully retrieved.
Can I ask your advice if my conversion is correct or did i missed something...
Or is there a better way to convert this or you have answers why this problem occur.
One thing that I suspect is the size of the struct, ANSI or Unicode, and the arrangement of the variables, structs.
Please advise - thanks.
sample 2:
////////////////
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct1
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct2
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num2;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct3
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = size + 1)]
public string chars;
[MarshalAs(UnmanagedType.I4)]
public Int32 num3;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct struct4
{
[MarshalAs(UnmanagedType.I4)]
public Int32 num4;
[MarshalAs(UnmanagedType.Struct)]
public Data DataMsg;
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct Data
{
//[FieldOffSet(0)]
public struct1 str1;
//[FieldOffSet(0)]
public struct2 str2;
//[FieldOffSet(0)]
public struct3 str3;
}
}
////////////////
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
选择 Pack=1 没有明显的理由,大多数 C 编译器的默认值是 8,就像 .NET 一样。偏移量 6 处的 MsgData 不确定。在测试 C 程序中使用 sizeof 和 offsetof() 来找出所有内容的位置。与测试 C# 程序中的 Marshal.SizeOf 和 OffsetOf() 进行比较。在他们完全同意之前,这不会起作用。
There's no obvious reason why you chose Pack=1, the default for most C compilers is 8, just like .NET. MsgData at offset 6 is iffy. Use sizeof and offsetof() in a test C program to find out where everything is located. Compare with Marshal.SizeOf and OffsetOf() in a test C# program. This isn't going to work until they agree exactly.