如何封送包含从C到C#的并集的结构

有人可以帮我以下吗?

我有一个用C编写的dll,想从C#中调用其中的某个函数。

该函数返回指向结构的指针。结构如下:

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,其定义为:

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#代码:

[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定义为:

[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#中定义联合的某种方式。

感谢您的帮助, 米奇。

zhaienpeng3 回答:如何封送包含从C到C#的并集的结构

我已经解决了这个问题。

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

所以代替:

[FieldOffset(0)]
long l;
[FieldOffset(0)]
ulong ul;

我应该有:

[FieldOffset(0)]
int l;
[FieldOffset(0)]
uint ul;

因为在C#int和uint中为4个字节宽。

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

public long num_ele;

我需要:

public int num_ele;

现在一切正常。

本文链接:https://www.f2er.com/2596359.html

大家都在问