将结构数组从非托管C ++函数返回到C#

时间:2018-11-21 13:12:43

标签: c# c++ .net unmanaged managed

我目前正在一个小组项目中,除了GUI用C#完成之外,所有代码都用C ++完成。

在C ++中,我们使用的功能是从文件中读取格式化的文本,并将其分隔为结构数组,例如:

typedef struct example{
    string id;
    string name;
    string email;
    char status;
    string phone_number;
 }example;

和一个数组:

example* example_arr=new example[10];

然后,我们要从C ++函数返回该数组,并在C#(DLLImport)中使用它以在表单中显示该信息。

当我开始考虑C#部分的实现时,我意识到我对如何实现它一无所知,因为我从未见过C#中使用非托管内存,因此我开始寻找可能的解决方案,但是大多数我发现的情况中,有一些是关于发送相反方向的信息(从C#到C ++)的,或者在解释上还不清楚。我从他们那里得到的唯一一件事确实是,编组的概念可能有用,但是,我实在无法绕过它。

老实说,我很乐意就该主题提供任何帮助,即使我没有使用C#处理非托管内存的经验,我也确实希望实现它。

编辑:

我尝试实现汉斯的建议,但遇到了问题。 C#代码运行,执行C ++函数,直到到达return语句并停止为止(不中断/抛出,就像它在等待发生的事情一样冻结),C ++函数就会运行,这反过来又阻止了C#代码的继续它正在运行。

这是代码(为了测试我简化了结构):

C ++

///header file
typedef struct example
{
    int num;
    char str[5];
}example;

extern "C" __declspec(dllexport) int __stdcall test(a arr[],int len);

///Cpp file
int __stdcall test(example* arr,int len)
{
    for (int i = 0; i < len; i++)
    {
        arr[i].num = i;
        std::cout <<"arr["<<i<<"].num = "<< arr[i].num<<"\n";//for debugging purposes
        strcpy(arr[i][0].str, "test");
    }
    std::cout << "not yet\n";
    return -1;//*does not get executed*
}

C#

public partial class Form1 : Form
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct example
    {
        public int num;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
        public string str;
    };

    [DllImport("unmanaged.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern int test(out example[] arr,int len);

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)//Form Loaded Event function
    {
        example[] arr = new example[10];
        int res = test(out arr,10);//*Code freezes here*

        Debug.WriteLine(res);
        _text.Text =arr[0].str;
    }
}

调试窗口中的输出为(如果一切正常,应以-1结尾):

arr[0].num = 0
arr[1].num = 1
arr[2].num = 2
arr[3].num = 3
arr[4].num = 4
arr[5].num = 5
arr[6].num = 6
arr[7].num = 7
arr[8].num = 8
arr[9].num = 9
not yet

我觉得这很奇怪,可能是与[out]修饰符相关的机制,但是我不知道。

0 个答案:

没有答案
相关问题