Answer the question
In order to leave comments, you need to log in
How to fix AccessViolation when reading a pointer read with CArchive?
There are two projects: DLL MFC to designate the functionality and .NET's to read the functionality of the library.
Almost all functions defined in the library work, except for one that reads objects from a file using CArchive (these objects were previously written to the file, no errors occurred, the serialization method is defined, DECLATE / IMPLEMENT is defined, there is an empty constructor)
[DllImport("testlib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void ReadFromFile([MarshalAs(UnmanagedType.LPStr)] string path);
std::vector<Fruit*> plate; // Вектор, в котором будем хранить считанные объекты
//....
extern "C" _declspec(dllexport) void __stdcall ReadFromFile(char* path)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CFile file(CString(path), CFile::modeRead);
CArchive ar(&file, CArchive::load);
int n;
ar >> n;
for (int i = 0; i < n; i++)
{
Fruit* fruit;
ar >> fruit;
plate.push_back(fruit);
auto cstrName = fruit->name; // Для наглядности. Именно в этом моменте возникает исключение AccessVIolation
}
ar.Close();
file.Close();
}
extern "C" _declspec(dllexport) void __stdcall WriteIntoFile(char* path)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CFile file(CString(path), CFile::modeCreate | CFile::modeWrite);
CArchive ar(&file, CArchive::store);
ar << plate.size();
for (auto o : plate)
{
ar << o;
}
ar.Close();
file.Close();
}
#ifndef FRUIT_H
#define FRUIT_H
#include "pch.h"
class Fruit : public CObject
{
DECLARE_SERIAL(Fruit);
public:
CString name;
Fruit();
Fruit(CString cname);
~Fruit();
virtual void Serialize(CArchive& ar);
};
#endif
#include "pch.h"
#include "Fruit.h"
IMPLEMENT_SERIAL(Fruit, CObject, 1);
void Fruit::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if (ar.IsStoring())
{
ar << name;
}
else
{
ar >> name;
}
}
Fruit::Fruit(CString cname)
{
name = cname;
}
Fruit::Fruit() {}
Fruit::~Fruit() {}
Answer the question
In order to leave comments, you need to log in
Whether it is not enough someone the decision of a similar problem is required.
The bottom line is that at first CArchive writes the size of the collection when writing, and then the collection itself. And when reading from a file, we use CArchive to first read the size of the collection, which is in the file, and then each object.
So, the error was quite simple - we wrote down the size as vectorObject.size() - which returns a size_t object with a size of 8 bytes, and read the size into an INT, the size of which is 4 bytes, thereby continuing to read objects from the file - NULL objects were generated.
To solve it, it is enough to either write the size as (INT) vectorObject.size() and read the size also in INT.
Either write vectorObject.size() -> size_t value, and read accordingly too:
size_t count;
ar >> count;
I don’t know what is in CArchive and in general I haven’t picked up MFC for a long time, but I assume that you need to use this option:
Fruit fruit;
ar >> fruit;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question