繁体   English   中英

如何将结构从非托管C ++程序传递到C#程序?

[英]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

InAttributeOutAttribute组合在一起时,将其应用于数组和格式化的,不可复制的类型时特别有用。 仅当您同时应用这两个属性时,呼叫者才能看到被呼叫者对这些类型所做的更改。 [...]

最终解决方案:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM