簡體   English   中英

如何在C#中封送結構數組?

[英]How to marshal an array of structure In C#?

我必須在C#中調用C ++ dll。 dll的頭文件如下(簡化):

// C ++的標題

struct vector
{
    float x;
    float y;

    vector()
    {}

    vector(float x0, float y0)
    {
        x = x0;
        y = y0;
    }
};

struct unmanaged_struct
{
    int int_var;
    float float_var;
    char* chars_var;
    vector vector_var;

    unmanaged_struct(int i, float f, char* ch, float vec_x, float vec_y) 
    {
        int_var = i;
        float_var = f;
        chars_var = ch;
        vector_var = vector(vec_x, vec_y);
    }
};

//此函數用於輸出struct實例的所有變量值

extern "C" __declspec( dllexport )  void unmanagedstruct_summary(unmanaged_struct* us_list, int length);

我在C#中定義了以下類

// CSHARP

[StructLayout(LayoutKind.Sequential)]
public class Vector
{
    public float x;
    public float y;

    public Vector(float f1, float f2)
    {
        x = f1;
        y = f2;
    }
}

[StructLayout(LayoutKind.Sequential)]
public class UnmanagedStruct 
{ 
    public int int_var;
    public float float_var;
    public string char_var;
    public Vector vector_var;

    public UnmanagedStruct(int i, float f, string s, Vector vec)
    {
        this.int_var = i;
        this.float_var = f;
        this.char_var = s;
        this.vector_var = vec;
    }
}

class UnmanagedDllCallTest
{
    [DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
    public  static extern void unmanagedstruct_summary([Out]UnmanagedStruct[] usList, int length);    

  static void Main(string[] args)
    {

        UnmanagedStruct[] usList = new UnmanagedStruct[1];
        usList[0] = new UnmanagedStruct(1, 1.0f, "aa", new Vector(10, 1));       
        usList[1] = new UnmanagedStruct(2, 2.0f, "ba", new Vector(20, 2));  
        UnmanagedDllCallTest.unmanagedstruct_summary(usList, 2);
}

輸出如下:

unmanaged_struct摘要:

0

1.12104e-044

未處理的異常:System.AccessViolationException:嘗試讀取或寫入受保護的內存。 這通常表明其他內存已損壞。 在c:\\ users \\ dynaturtle \\ docnt nts \\ visual studio 2010 \\ Projects \\ callunmanageddll \\ callunmanageddll \\ Program中的callunmanageddll.Program.Main(String [] args)中的callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStr uct [] usList,Int32長度) .cs:lin e 68

C ++ dll正常,因為我已經用C ++編寫了測試,並且該功能運行良好。 我已經閱讀了該線程,但是看來該解決方案在我的情況下不起作用。 有什么建議么? 提前致謝!

使用Marshal.PtrToStructure 有一個樣品在這里

因此,您必須將方法的簽名從out結構數組更改為out IntPtr。 但是,您需要知道要傳遞的緩沖區的大小。

public struct Vector
{
    public float x;
    public float y;

}

public struct UnmanagedStruct 
{ 
    public int int_var;
    public float float_var;
    public string char_var;
    public Vector vector_var;

}

class UnmanagedDllCallTest
{
    [DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
    public static extern void unmanagedstruct_summary([Out] IntPtr ptr, int length);    

  static void Main(string[] args)
  {

    for(int i=0; i<length; i++)
    {
        UnmanagedStruc st;
        Marshal.PtrToStructure(ptr, st);
        // increment ptr and move forward
    }

}

第一:Vector和UnmanagedStruct應該是結構,而不是類。

JIC我會分享我的方法。 也許這不是我一次花時間來解決問題的預期答案。

我具有以下結構來公開DLL中的某些數據。

//C++ code
    struct State
    {
        const wchar_t * name;
        unsigned int state; 
    };

APIENTRY bool get_states(H_PRCSR, MacroState *, const int sz); //pay attention, function accepts already allocated array and size for it

從C ++接受此數據,我可以這樣做

std::vector<State> states(desired_size);
get_states(hparser, &states[0], states.size());

為了在C#上執行相同的操作,我使用了以下方法

//C#
[StructLayout(LayoutKind.Sequential)]
public struct Status
{
   public IntPtr name;
   public uint state;

   public string getName()
   {
     if (name == IntPtr.Zero) return "<no-value>";
     return Marshal.PtrToStringUni(name);
   }
}

//And import function...

[DllImport(dll, CallingConvention = CallingConvention.Winapi)]
private static extern bool get_states(IntPtr p, [Out]MacroFlag[] flags, int flags_size);

//And simple decoder
public static Status[] getAll(IntPtr p, int size)
{
   var results = new Status[size];

   get_states(p, results, size);

   return results;
}

因此,我看到了執行此操作的不同方法。 這就是其中之一。 它對我有用。 也許,這篇文章無法解決問題,但將是一個不錯的起點

暫無
暫無

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

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