Я пытаюсь портировать некоторый код из нашего приложения 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 ++. Мои извинения за стену текста.