Портирование двоичного файла с чтением кода C ++ на C # - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь портировать некоторый код из нашего приложения C ++, чтобы гарантировать, что файлы лицензий совместимы с обоими приложениями.

Я пытался пометить функции как внешние, однако это открыло целую другую банку с червями, которую я не хотел бы вникать, учитывая, что это моя последняя неделя у моего нынешнего работодателя.

Код C ++, который я хотел бы перенести, выглядит следующим образом:

std::fstream licenceFile(filePath, std::ios::in | std::ios::binary);
licenceFile.read((char *) &this->m_FileData, sizeof(this->m_FileData));

m_FileData является структурой и выглядит следующим образом:

struct LicManKeyFileData
{
    BYTE m_EncryptedKey[255];
    WCHAR m_MacAddress[33];
    WCHAR m_PreviousMacLicense[33];
    WCHAR m_SoftwareName[16];
    WCHAR m_ClientName[65];
    BYTE m_Version;
    BYTE m_EncryptionLength;
    time_t m_LicenseTime;
};

Я пробовал несколько способов репликации этого в C #, сначала читая элемент файла по элементу, например:

BinaryReader reader = new BinaryReader(licenceFileStream, Encoding.BigEndianUnicode);

licenceFileData.EncryptedKey = reader.ReadBytes(licenceFileData.EncryptedKey.Length);

byte[] mac = new byte[sizeof(char) * licenceFileData.MacAddress.Length];
mac = reader.ReadBytes(mac.Length);

Что-то странное, что я заметил об этом методе, это то, что многие значения были заданы равными 204, по-видимому, произвольно, когда они правильно читаются в приложении C ++, поэтому мне пришлось добавить это:

if (mac[0] == 204)
    mac[0] = 0;

Что не имеет смысла для меня, это не проблема выравнивания, чтение из байта до или после этого дает полностью мусорные значения (китайские символы), и эта проверка и присвоение 0 первому индексу позволяет мне получить правильное значение.

Другой метод, который я попробовал, был найден здесь, в StackOverflow, и выглядит следующим образом:

 public static T ReadStruct<T>(this BinaryReader reader) where T : struct
 {
     Byte[] buffer = new Byte[Marshal.SizeOf(typeof(T))];
     reader.Read(buffer, 0, buffer.Length);
     GCHandle handle = default(GCHandle);

     try
     {
        handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
     }
     finally
     {
        if (handle.IsAllocated)
            handle.Free();
     }
 }

Как ни странно, этот метод также возвращает некоторые значения как 204, где приложение C ++ считывает их как правильное значение.

Структура, которую я использую в C #, выглядит следующим образом:

unsafe struct LicenceFileDataS
{
    internal fixed byte m_EncryptedKey[255];
    internal fixed char m_MacAddress[33];
    internal fixed char m_PreviousMacLicense[33];
    internal fixed char m_SoftwareName[16];
    internal fixed char m_ClientName[65];
    internal byte m_Version;
    internal byte m_EncryptionLength;
    internal long m_LicenseTime;
}

Кто-нибудь знает лучший способ портирования этого кода или как я могу исправить значения, которые читаются как 204? Он отлично работает в C ++. Мои извинения за стену текста.

...