如何在 C# 中编组结构数组? [英] How to marshal an array of structure In C#?

查看:58
本文介绍了如何在 C# 中编组结构数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 C# 中调用 C++ dll.并且dll的头如下(简化):

I have to call a C++ dll in C#. And the header of the dll is as following(simplified):

//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实例的所有变量值

// this function is used to output all the variable values of the struct instance

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

我在 C# 中定义了以下类

And I defined following class in 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 摘要:

unmanaged_struct summary:

0

1.12104e-044

1.12104e-044

未处理的异常:System.AccessViolationException:试图读或写保护记忆.这通常是一个迹象其他内存已损坏.在callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStruct[] usList, Int32 长度) atcallunmanageddll.Program.Main(String[]args) 在 c:\users\dynaturtle\documents\视觉工作室2010\Projects\callunmanageddll\callunmanageddll\Program.cs:lin68

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStr uct[] usList, Int32 length) at callunmanageddll.Program.Main(String[] args) in c:\users\dynaturtle\docume nts\visual studio 2010\Projects\callunmanageddll\callunmanageddll\Program.cs:lin e 68

C++ dll 没问题,因为我已经用 C++ 编写了测试并且该函数运行良好.我已阅读此线程,但似乎解决方案没有"t 在我的情况下工作.有什么建议么?提前致谢!

The C++ dll is OK as I have written test in C++ and the function works well. I have read this thread but it seems the solution didn't work in my case. Any suggestions? Thanks in advance!

推荐答案

使用 Marshal.PtrToStructure.此处有一个示例.

因此,您必须将方法的签名从 out 结构数组更改为 out IntPtr.但是,您需要知道正在传出的缓冲区的大小.

So you would have to change the signature of the method from out structure array to out IntPtr. However, you need to know the size of the buffer being passed out.

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
    }

}

这篇关于如何在 C# 中编组结构数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆