我目前正在一个小组项目中,除了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]修饰符相关的机制,但是我不知道。