I m developing a C# CE application to read data from binary files which created by C++ progam to do item validation.

Below is the coding of the C++ program..

// File Name: Ean2an.bin which is created by struct 
    struct EAN2AN_TYPE 
    {
    __int64     ean:40;     // 5 bytes, up to 12 digits
    __int64     rec_no:24;  // 3 bytes rec no in the c_ItemMaster File, up to 16 million  records
    };

    // After bind data to struct, wil create the binary file
   bool CreateBin_EAN2AN_TYPE()
   {
    if(mn_RecordCount_EAN2AN_TYPE == 0) return false;

    FILE   *binfile;

    qsort(mc_EAN2AN_TYPE, mn_RecordCount_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), qsort_EAN2AN_TYPE);
    try
    {
        binfile = fopen(ms_Path_EAN2AN_TYPE, "wb");
        fwrite(&mc_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), mn_RecordCount_EAN2AN_TYPE, binfile);
    }
    catch(Exception ^ex)
    {
        TaskProgramLibrary::Message::ERR("Create EAN2AN_TYPE.bin fail!\r\n       " + ex->Message);
    }
    finally
    {
        fclose(binfile);

        mdw_FileSize_EAN2AN_TYPE = FileSize(ms_Path_EAN2AN_TYPE);
    }

    return true;
      }

I tried to read the data by using binary read(based on position) and use bitconverter to convert to int64 or using Marshal.PtrToStructure, but the value return is incorrect. Then i tried to read 5 bytes instead of 8 bytes from the file, but the value return stil incorrect.

Below is the written C# coding
    //Struct created in C#
   [StructLayout(LayoutKind.Sequential)]
        public struct EAN2AN_TYPE
        {
            [MarshalAs(UnmanagedType.I8)]
            public Int64 ean;
            [MarshalAs(UnmanagedType.I8)]
            public Int64 rec_no;
        } 

    //The ways i tried to read in C#
    //1.Read Int64 by Binary 
    private void ReadByBinary()
         {
            using (BinaryReader b = new BinaryReader(_fs))
            {
                while (b.PeekChar() != 0)
                {
                    Int64 x = b.ReadInt64();
                    Console.WriteLine(x.ToString());

                }
            }

        }

   //2.Using Marshal to convert the Intptr to struct's field type
    private object ReadByMarshal(Type iType)
        {
            _oType = iType;// typeof(System.Int64);
            byte[] buffer = new byte[Marshal.SizeOf(_oType)];
            //byte[] buffer = new byte[5];

            object oReturn = null;

            try
            {
                _fs.Read(buffer, 0, buffer.Length);

                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                oReturn = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), _oType);
                handle.Free();

                return oReturn;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


    //3. Use Binary and use bit converter to convert to Int64
     private void ReadByBinaryAndUseBitConverter()
        {
            using (BinaryReader b = new BinaryReader(_fs))
            {
                byte[] x = b.ReadBytes(8);
                Int64 y = BitConverter.ToInt64(x, 0);
                Console.WriteLine(y);

                byte[] x2 = b.ReadBytes(8);
                Int64 y2 = BitConverter.ToInt64(x2,0);
                Console.WriteLine(y2);
            }

        }


    //4. Use Marshal and convert to struct
    public EAN2AN_TYPE  GetStructValue()
        {

            byte[] buffer = new byte[Marshal.SizeOf(typeof(EAN2AN_TYPE)];

            EAN2AN_TYPE oReturn = new EAN2AN_TYPE();

            try
            {
                //if (EOF) return null;

                _fs.Read(buffer, 0, buffer.Length);
                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                IntPtr rawDataPtr = handle.AddrOfPinnedObject();

               oReturn = (EAN2AN_TYPE)Marshal.PtrToStructure(rawDataPtr, typeof(EAN2AN_TYPE));

                handle.Free();

                if (_fs.Position >= _fs.Length)
                    Close();

                return oReturn;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

The initial C++ code is written by vendor. I only can try understand by read the C++ code. As my understanding.. it just create binary file and write in the data.. I cant find any encoding/convert part from code ..

I tried to convert the 1st ean(978086288751) to byte[] manually by code.
The byte[] is 111 93 124 186 227 0 0 0 which is different with the result i get..

Below is the result from my testing
Result read 5 bytes : 17 0 0 0 0
ean : 17
Result read 8 bytes :17 0 0 0 0 108 94 5
ean :386865365256241169

Anybody have any idea?

Thanks in advance

I don't know C++, but it appears as though the structure packs to values into a single Int64 value. if this is the case, try reading the value as a Int64 and masking and bit shifting to get the values.

            Int64 val = 978086288751L;
            Int64 ean = default(Int64);
            Int64 rec_no = default(Int64);

            ean = val & 0x000000ffffffffffL;
            rec_no = Convert.ToInt64(Convert.ToUInt64( val) & 0xffffff0000000000L) >> 40;
This article has been dead for over six months. Start a new discussion instead.