簡體   English   中英

如何封送包含從 C 到 C# 的聯合的結構

[英]How to marshal a structure containing a union from C to 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# 中定義聯合的方式是我所缺少的。

感謝您的幫助,米奇。

我已經解決了這個問題。

IC,long(和 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;

現在一切正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM