首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将包含并集的结构从C编组到C#

如何将包含并集的结构从C编组到C#
EN

Stack Overflow用户
提问于 2020-03-23 23:21:48
回答 1查看 97关注 0票数 2

有没有人可以帮我做以下事情?

我有一个用C写的动态链接库,想从C#中调用其中的某个函数。

该函数返回一个指向结构的指针。结构是这样的:

代码语言:javascript
运行
复制
typedef struct
{
    char          crv_name[40];
    char          crv_name2[12];
    char          units[40];
    char          creator[24];     
    char          index_units[8];
    double        first_dep_tim;
    double        last_dep_tim;
    double        level_spacing;
    EmptyValU     empty_val;
    long          num_ele;
}

现在,我知道(从C客户端调用此函数)最后一个成员(num_ele)将被设置为1。

现在,倒数第二个成员的类型为EmptyValU,其定义如下:

代码语言:javascript
运行
复制
typedef union
{
  double   d;
  float    f;
  long     l;
  ulong    ul;
  short    s;
  ushort   us;
  char     c;
}EmptyValU;

现在,我可以把它叫做C#,然后在empty_val之前读取所有内容。我对num_ele的值是无稽之谈,因为在empty_val之后,我的内存显然没有对齐。

下面是我的C#代码:

代码语言:javascript
运行
复制
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CurveInfo
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
    public string crv_name;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
    public string crv_name2;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
    public string units;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
    public string creator;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string index_units;
    public double first_dep_tim;
    public double last_dep_tim; 
    public double level_spacing; 
    [MarshalAs(UnmanagedType.Struct, SizeConst = 8)]
    public EmptyValU empty_val;
    public long num_ele;
}

我将EmptyValU定义为:

代码语言:javascript
运行
复制
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct EmptyValU
{
    [FieldOffset(0)]
    public double d;
    [FieldOffset(0)]
    public float f;
    [FieldOffset(0)]
    long l;
    [FieldOffset(0)]
    ulong ul;
    [FieldOffset(0)]
    short s;
    [FieldOffset(0)]
    ushort us;
    [FieldOffset(0)]
    char c;
}

就像我说的,当我调用返回指向这样一个结构的指针的函数时,所有的值都被正确填充,直到EmptyValU成员,它和num_ele都没有被正确填充。为了保持对齐的正确性,我在C#中定义联合的方式缺少一些东西。

谢谢你的帮助米奇。

EN

回答 1

Stack Overflow用户

发布于 2020-03-25 23:06:01

我已经解决了这个问题。

长整型(和ulong)是4字节宽,但在C#中是8字节宽。

因此,不是:

代码语言:javascript
运行
复制
[FieldOffset(0)]
long l;
[FieldOffset(0)]
ulong ul;

我应该有:

代码语言:javascript
运行
复制
[FieldOffset(0)]
int l;
[FieldOffset(0)]
uint ul;

因为在C#中,int和uint是4字节宽的。

出于同样的原因,在C#端,而不是:

代码语言:javascript
运行
复制
public long num_ele;

我需要:

代码语言:javascript
运行
复制
public int num_ele;

现在一切都正常了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60816442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档