编组时大尺寸阵列

时间:2012-04-29 10:18:04

标签: c# marshalling

我在(.dll)文件中使用c函数,该文件接受struct数组的引用并返回一个字节,用于确定我的操作是否成功。 它在c项目中运作良好 当我发送一个小尺寸阵列(最多7个元素)时效果很好 之后就是假的!!

数组来自以下结构

    [StructLayout(LayoutKind.Sequential)]
    public struct MainStruct
    {
        [MarshalAsAttribute(UnmanagedType.Struct, SizeConst = 5)]
        public Struct2 Struct2Object;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem1;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem2;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem3;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem4;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem5;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem6;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem7;

        [MarshalAsAttribute(UnmanagedType.U8, SizeConst = 1)]
        public UInt64 Elem8;

    };

3 个答案:

答案 0 :(得分:0)

您的结构中似乎有8个字节的硬编码。当然,如果超过这个限制,你将会受到内存损坏。

如果有“无限量”字节需要“发送”,我会使用Marshal.AllocHGlobal分配一个非管理缓冲区,并将其传递给非托管函数。

答案 1 :(得分:0)

    __declspec(dllexport) TU08 GetBuffer(MainStruct *OBJ)
    {
    TU64 SelectedOBIS;
    TU08 XdrBuffer[Dlms_mXdrMaxBuffer];
    TU08 *pXdrBuffer;
    TU32 i;
    TU32 NumberOfElements;

    pXdrBuffer = XdrBuffer;
    SelectedOBIS = ProfilesData[LOG_ID_1].ProfilesOBISCodes;

        pXdrBuffer = XdrBuffer;
        Dlms_gXdrInitBuffer();
        /////// Get Data ///////
        if(Main_iSendGetRequest(SelectedOBIS, 7, 2, XdrBuffer) == false)
            return 0;
        /////// Extract Data ///////
        if(*XdrBuffer == Dlms_mXdrArray)
        {
            NumberOfElements = *(pXdrBuffer + 1);
            pXdrBuffer += 2; // 2 for array tag and its number of fields 
            for(i=0; i<NumberOfElements; i++)
            {
                if(*pXdrBuffer == Dlms_mXdrStruct)
                {
    pXdrBuffer += 2; // 2 for struct tag and its number of fields 
    pXdrBuffer = gGetDateTime(pXdrBuffer, &OBJ[i].TimeStamp);
    pXdrBuffer = gGetLongUnsigned(pXdrBuffer, &OBJ[i].StatusRegister);
    pXdrBuffer = gGetUnsigned(pXdrBuffer, &OBJ[i].EventCode);
    }
            }
        }
    return 1;
}

这是用过的功能。

这是C

中的结构
typedef struct
{
    Struct2 Struct2OBject;
    TU64 Elem1;
    TU64 Elem2;
    TU64 Elem3;
    TU64 Elem4;
    TU64 Elem5;
    TU64 Elem6;
    TU64 Elem7;
    TU64 Elem8;
} MainStruct;

该职能的元帅是

    [DllImport("dll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern byte GetBuffer([In, Out] MainStruct[] Profile);

关键是它在C中运行良好,并且如果传递给函数的数组大小为7或更小,也可以在windows窗体应用程序中正常工作!

答案 2 :(得分:0)

我试图使用指针来获取数据:( .. 直到这一点,它还可以。

MainStruct OBJ = (MainStruct)Marshal.PtrToStructure(pointertostruct, typeof(MainStruct));

指针获取数据,但它只是用零初始化对象!