1

構造体の配列への参照を取得し、操作が成功したかどうかを判断するバイトを返す(.dll)ファイルでac関数を使用します。これはcプロジェクトでうまく機能し、小さいサイズの配列(最大7要素)を送信するとうまく機能し、その後はfalseになります。

配列は次の構造体からのものです

    [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;

    };
4

3 に答える 3

0

ポインタを使用して:(..のデータを取得しようとしましたが、この時点までは問題なく動作します。

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

ポインタはデータを取得しますが、オブジェクトをゼロで初期化するだけです!!

于 2012-05-03T11:19:15.330 に答える
0

構造体に8バイトがハードコーディングされているようです。もちろん、その制限を超えると、メモリが破損します。

「送信」されるバイト数が無制限になる可能性がある場合は、Marshal.AllocHGlobalを使用してアンマネージバッファを割り当て、アンマネージ関数に渡します。

于 2012-04-29T10:46:31.547 に答える
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);

重要なのは、関数に渡される配列のサイズが7以下の場合、Cで適切に機能し、Windowsフォームアプリケーションでも適切に機能することです。

于 2012-05-02T12:06:06.980 に答える