【问题标题】:Pass c# structure array to c++将 c# 结构体数组传递给 c++
【发布时间】:2015-01-25 11:07:02
【问题描述】:

我在 c++ dll 上工作并且有任何问题! 我的头文件是这样的

struct ST_DevInfo
{
    EN_DevType de_type;        
    int screen_width;          
    int screen_height;         
    char dev_name[256];        
    char id[14];               
    char sboox_version[16];    
    char fpga_version[16];     
};

extern "C" __declspec(dllexport) int CB_GetDeviceList(ST_DevInfo* buff,int length);

和c++代码

int CB_GetDeviceList(ST_DevInfo* buff,int length)
{
    buff = (ST_DevInfo *)malloc(sizeof(ST_DevInfo) * length);

    return GetDeviceList(buff, length);
}

现在我像这样在c#中使用这个函数

[StructLayout(LayoutKind.Sequential)]
        struct ST_DevInfo
        {
            [MarshalAs(UnmanagedType.I4)]
            public EN_DevType de_type;
            [MarshalAs(UnmanagedType.I4)]
            public int screen_width;
            [MarshalAs(UnmanagedType.I4)]
            public int screen_height;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 256)]
            public char[] dev_name;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 14)]
            public char[]  id;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 16)]
            public char[]  sboox_version;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 16)]
            public char[]  fpga_version;
        };

[DllImport(dllName, EntryPoint = "CB_GetDeviceList", SetLastError = true, ExactSpelling = true,
            CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        public static extern
            int CB_GetDeviceList([MarshalAs(UnmanagedType.LPArray)] ref ST_DevInfo[] buff, 
                                    int length);

最后我像这样在我的程序中使用这个函数

ST_DevInfo[] buff = new ST_DevInfo[dev_length];
int ret = BBIA.CB_GetDeviceList( ref buff, dev_length);

但在从 CB_GetDeviceList 检索后,我的 buff 变量已分配但没有任何值(包含 0x00)。我用 C++ 测试它,它工作正常!! 我认为这行有问题

buff = (ST_DevInfo *)malloc(sizeof(ST_DevInfo) * 长度);

【问题讨论】:

  • 删除 C++ 代码中的malloc,因为您已经将分配的内存传递给函数。您实际上是在将数据写入一个新数组,从不修改从 C# 传递的数据。

标签: c# c++ arrays structure


【解决方案1】:

在您的 C# 代码中,您正在这样做:

ST_DevInfo[] buff = new ST_DevInfo[dev_length];
int ret = BBIA.CB_GetDeviceList( ref buff, dev_length);

这是分配一个数组,并将它(通过双指针,因为你有 ref)传递给 C++ 代码。

在您正在执行的 C++ 代码中:

int CB_GetDeviceList(ST_DevInfo* buff,int length)
{
    buff = (ST_DevInfo *)malloc(sizeof(ST_DevInfo) * length);
    return GetDeviceList(buff, length);
}

它采用数组(而不是双指针)并将该(本地)指针更改为指向一些新内存。所以 C# 中的原始数组永远不会被 C++ 代码触及。

首先,完全删除malloc 调用。然后将您的 pinvoke 更改为:

[DllImport( ... )]
public static extern int CB_GetDeviceList( [In, Out] ST_DevInfo[] buff, int length );

并像以前一样调用,但没有ref。需要In, Out 告诉编组器您希望 pinvoke 调用修改数据。并非在所有情况下都需要它们,但在你的情况下,我不能 100% 确定,所以我会保留它们以防万一。

【讨论】:

    猜你喜欢
    • 2011-04-06
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多