![](/img/trans.png)
[英]How can I pass struct from C# managed to C++ unmanaged DLL and get struct in result?
[英]How do I pass a struct from an unmanaged C++ program to a C# program?
这是我的第二篇文章。
这是我要执行的操作:从c#调用非托管c ++程序,从c#程序传入结构数组,然后从c ++程序返回结构数组的更新版本。
这是调用c#程序:
using System;
using System.Runtime.InteropServices;
namespace TestCallingC
{
class Program
{
[DllImport(@"..\..\..\Debug\TestCProgram.dll")]
public static extern void testfunc(teststruc[] ts);
static void Main(string[] args)
{
teststruc[] teststructs = new teststruc[6];
for (int i = 0; i < teststructs.Length; i++)
{
teststructs[i].int1 = (i + 1) * 100;
teststructs[i].int2 = (i + 1) * 100;
}
testfunc(teststructs);
for (int i = 0; i < teststructs.Length; i++)
{
Console.WriteLine("Int1 = {0}", teststructs[i].int1);
Console.WriteLine("Int2 = {0}", teststructs[i].int2);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct teststruc
{
[MarshalAs(UnmanagedType.I4)]
public int int1;
[MarshalAs(UnmanagedType.I4)]
public int int2;
}
}
这是返回的c ++程序:
extern "C" __declspec(dllexport) void testfunc (teststruc* ts)
{
int i;
for (i = 0; i < 6; i++)
{
ts[i].int1 = i;
ts[i].int2 = i;
}
for (i = 0; i < 6; i++)
{
printf("ts[%d].int1 = %d\n", i, ts[i].int1);
printf("ts[%d].int2 = %d\n", i, ts[i].int2);
}
return;
}
我上面介绍的版本允许c ++程序查看和打印从c#程序传递的入站结构。 当控件传递回c#程序时,数据与最初设置的数据相同。 它允许通过调用c ++程序更新结构。 这是控制台输出。 第一部分显示了称为c ++程序的更新字段。 第二部分是c#调用者最初设置的内容:
ts[0].int1 = 0
ts[0].int2 = 0
ts[1].int1 = 1
ts[1].int2 = 1
ts[2].int1 = 2
ts[2].int2 = 2
ts[3].int1 = 3
ts[3].int2 = 3
ts[4].int1 = 4
ts[4].int2 = 4
ts[5].int1 = 5
ts[5].int2 = 5
Int1 = 100
Int2 = 100
Int1 = 200
Int2 = 200
Int1 = 300
Int2 = 300
Int1 = 400
Int2 = 400
Int1 = 500
Int2 = 500
Int1 = 600
Int2 = 600
如果将“ ref”标签添加到c#调用签名,则从c ++程序返回的结构为null:
[DllImport(@"..\..\..\Debug\TestCProgram.dll")]
public static extern void testfunc(ref teststruc[] ts);
testfunc(ref teststructs);
问题:为了使结构能够在c ++程序中正确更新并返回给c#程序,需要对c ++和c#程序中的接口进行哪些更新?
我发现了很多有关类似事物的信息,但是没有任何东西给我正确的组合以使之实现。 任何建议都欢迎。
谢谢。 格雷格
随机的疯狂猜测:
[DllImport(@"..\..\..\Debug\TestCProgram.dll")]
public static extern void testfunc([In, Out] teststruc[] ts);
从MSDN :
将InAttribute和OutAttribute组合在一起时,将其应用于数组和格式化的,不可复制的类型时特别有用。 仅当您同时应用这两个属性时,呼叫者才能看到被呼叫者对这些类型所做的更改。 [...]
最终解决方案:
C ++(与初始版本相同)。
C#代码:
using System;
using System.Runtime.InteropServices;
namespace TestCallingC
{
class Program
{
[DllImport(@"..\..\..\Debug\TestCProgram.dll")]
public static extern void testfunc([In, Out] teststruc[] ts);
static void Main(string[] args)
{
teststruc[] teststructs = new teststruc[6];
for (int i = 0; i < teststructs.Length; i++)
{
teststructs[i].int1 = (i + 1) * 100;
teststructs[i].int2 = (i + 1) * 100;
}
testfunc(teststructs);
for (int i = 0; i < teststructs.Length; i++)
{
Console.WriteLine("Int1 = {0}", teststructs[i].int1);
Console.WriteLine("Int2 = {0}", teststructs[i].int2);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct teststruc
{
[MarshalAs(UnmanagedType.I4)]
public int int1;
[MarshalAs(UnmanagedType.I4)]
public int int2;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.