如何编组C#中的结构数组?

xia*_*o 啸 2 c# pinvoke

我必须在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);
    }
};
Run Code Online (Sandbox Code Playgroud)

//此函数用于输出struct实例的所有变量值

extern "C" __declspec( dllexport )  void unmanagedstruct_summary(unmanaged_struct* us_list, int length);
Run Code Online (Sandbox Code Playgroud)

我在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);
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

unmanaged_struct摘要:

0

1.12104e-044

未处理的异常:System.AccessViolationException:尝试读取或写入受保护的内存.这通常表明其他内存已损坏.at callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStr uct [] usList,int32 length)at clulmanageddll.Program.Main(String [] args)in c:\ users\dynaturtle\docume nts\visual studio 2010\Projects\callunmanageddll\callunmanageddll\Program .cs:lin e 68

C++ DLL是可以的,因为我已经用C++编写了测试,并且该函数运行良好.我已经读过这个帖子,但似乎解决方案在我的情况下不起作用.有什么建议?提前致谢!

Ali*_*tad 5

使用Marshal.PtrToStructure.有一个样品在这里.

因此,您必须将方法的签名从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
    }

}
Run Code Online (Sandbox Code Playgroud)