[C#] необработанное исключение типа "system.accessviolationexception" произошло в "xxxxx.dll"
У меня есть код c#, который вызывает dll (cpp build) и записывает текстовый файл (размером 12 МБ) txt-файла в переменную, вызывая cpp dll
Получение следующих ошибок :
{"Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена."}
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Что я уже пробовал:
c# code : // this is the code to call the dll (cpp build) <pre> private void button3_Click(object sender, EventArgs e) { try { System.Threading.ThreadStart starter = delegate { CallTheNumerOfTimesEx(1, 98600, "Thread1"); }; // 100000 95600 System.Threading.Thread thread = new System.Threading.Thread(starter); thread.Start(); thread.Join(); string outputFile = @"D:\SampleJFile.txt"; if (File.Exists(outputFile)) File.Delete(outputFile); string loging = someVariable // someVariable contains string size of 10 MB// using (StreamWriter writer = new StreamWriter(outputFile)) writer.WriteLine(toLog); obj.Information("Asdf", loging , "asdf"); // This is the (cpp build) dll function } catch (Exception ex) { tracelog.Error(ex); } MessageBox.Show(""); }
cpp-функция, записывающая полученные данные :
void Trace::Information (String^ category, String^ messageText, String ^stackTrace) { String ^oldCategory = traceMessage->category; TM->eventType = KTEventType::Information; TM->category = category; TM->errorCode = 0; TM->messageText = messageText; this->TM->timeStamp = DateTime::Now.ToString ("yyyy-MM-dd HH:mm:ss.fff"); if (stackTrace == nullptr) { System::Diagnostics::StackTrace ^st = gcnew System::Diagnostics::StackTrace (); TM->stackTrace = st->ToString (); } else TM->stackTrace = stackTrace; LogMessage (TM); TM->stackTrace = nullptr; TM->category = oldCategory; };
данные переменные объявляются следующим образом
private: TraceMessage ^TM; struct EXPORT_CLASS TraceMessage { public: KTEventType eventType; LPCWSTR category; KTWSTRING timeStamp; LPCWSTR machineName; LPCWSTR applicationName; LPCWSTR userName; LPCWSTR threadID; long errorCode; LPCWSTR messageText; LPCWSTR stackTrace; LPCWSTR errorSource; byte logLevel; }
void GenericLogger::LogMessage(ILogMessage^ logMessage) { bool sharedMemoryLockHeld = false; try { // Perform necessary validations // Validate the custom log message passed if(logMessage == nullptr) { throw gcnew ArgumentException("Custom log message passed to LogMessage method is null."); } // Validate the message id returned by the custom log message long messageId = logMessage->MessageId; // Ensure that the message id specified is non-negative if(messageId < 0) { throw gcnew ApplicationException("All custom message Ids must be positive integers. Please specify another message id for this custom log message."); } // Ensure that the message id specified is not a reserved message id // for TraceMessage message types if(messageId == 0) { throw gcnew ApplicationException("The message id '0' is reserved for TraceMessage message types. Please specify another message id for this custom log message."); } // Initialize the shared memory writer Init(); // Use the BinaryFormatter to serialize the custom message // to the memory stream MemoryStream^ pMemStream = gcnew MemoryStream(); BinaryFormatter^ pFormatter = gcnew BinaryFormatter(); pFormatter->Serialize(pMemStream, logMessage); // Get the serialized byte array from the memory stream array<unsigned char>^ arrSerializedBytes = pMemStream->GetBuffer(); if(arrSerializedBytes != nullptr) { // Get the length of the serialized byte array int customMessageLength = arrSerializedBytes->Length; if(customMessageLength > 0) { // The total message size = // [Field that stores the length of the message (4 bytes)] + // [Field that stores the message type (Trace/Custom/UnmanagedCustom (4 bytes))] + // [Field that stores the message Id (4 bytes)] + // [ Actual length of the serialized custom message]. int totalMessageSize = customMessageLength + 12; // Begin writing into the shared memory. This actually procures the // necessary locks for writing into shared memory m_pShmWriter->BeginWrite(totalMessageSize); sharedMemoryLockHeld = true; // Write the message type indicating that it is a // custom message m_pShmWriter->AddLong((long)LogType::Custom); // Write the message id associated with the message m_pShmWriter->AddLong(messageId); // Write the serialized byte array to the shared memory m_pShmWriter->Write((array<system::byte> ^)arrSerializedBytes); } } }// end try catch(Exception^ pEx) { // Rethrow the exception Trace::WriteLine(pEx->Message); } finally { if(sharedMemoryLockHeld) { //Release all acquired locks in shared memory. m_pShmWriter->EndWrite(); sharedMemoryLockHeld = false; } }
Может ли кто-нибудь предложить исправить эту проблему
Jochen Arndt
Из ваших фрагментов кода неясно, где происходит нарушение доступа, а также когда и как вызываются функции (например, что делает LogMessage ()?).
Большинство членов структуры TraceMessage являются указателями (LPCWSTR). Они будут действительны только в том случае, если назначенные объекты существуют и, следовательно, являются возможным источником вашей проблемы. Если это так, то они должны быть изменены на строковые объекты.
Greek Varak
Спасибо за ваш ответ яаар... я новичок в C++... На самом деле он ломается при
об..Информация("Asdf", loging , "asdf"); с ошибкой нарушения доступа.
он отлично работает, когда у нас есть samplejfile размером 9,99 Мб . Когда мы передаем 10 МБ текстового файла в библиотеку dll cpp, он терпит неудачу... Я попробую со строковыми объектами ... а сообщение журнала-это универсальная функция.
Jochen Arndt
параметр obj.Информация("впрыска", логин , "впрыска"); с нарушение прав доступа ошибка.
Начни с этого. Какова ценность "логинга"? Это параметр obj' действует? Проверьте код информационной функции и доступ к "loging".
Пожалуйста, не размещайте такие блоки кода в качестве комментариев. Они почти не читаются. Вы можете использовать зеленую ссылку "улучшить вопрос", чтобы добавить ее к вашему вопросу. Но публикуйте только код, связанный с этим вопросом (длинные вопросы также трудно читать, и многие, кто может помочь, пропустят их).
Greek Varak
Извини, Йохен, я сделал так, чтобы это был хороший вопрос, как ты и сказал ... На самом деле, когда я пытаюсь дебютировать через obj.information, нажав функцию F11, не отлаживается через dll... Вот тут я и ударил ....
Jochen Arndt
Без проблем.
Но это все еще неясно:
KTTrace::LogMessage(TraceMessage ^TM)
Что не соответствует
GenericLogger::LogMessage(ILogMessage^ logMessage)
Richard MacCutchan
Вам нужно использовать отладчик, чтобы проследить код и точно найти, где происходит исключение. Это должно помочь изолировать переменную, которая имеет плохой адрес.