Writing data using libxl library - c++

I am calling the xlCreateBook() function. Before that my program holds more memory because i am reading a huge file. After called the xlCreateBook() it returns the null pointr to the Sheet variable.
But once i loaded the less size file it xlCreateBook() functions working correctly. Help me to get out of this.

Which method returns a null pointer? AddSheet()? It's strange that it would be related to size to write, since at the sheet creation, you have not added data yet. What does Book::errorMessage() say when you get a null sheet pointer?
Maybe what you are trying to save is too big for the old xls format, and you should create an xlsx file, by using xlCreateXMLBook() instead?
If you really are lacking memory because of something else, there is not much that can be done by software if you lack physical memory. Except detecting it and returning a 'clean' error

Related

"Cast" the address of a Lua table to a Lua table

Say I have the address of a table - how would I "cast" a table variable to it? I'm not concerned about "bad practice" or crashes because this is just an individual problem.
I want to do something like
lua_table tab = *(lua_table*)0xaddr
...but within the Lua global environment.
I understand how bad this is but I really need to know if this is possible. It may not be the best way to do what I'm trying to do, but I'm quite certain it's the easiest and that it will work if this is possible. I am using Lua 5.1.4.
Lua exposes no API for doing this.
It would be easier and much more robust to fix your design rather than trying to force this to work.
In order to do what you're attempting, you must:
Get a pointer to the Lua table's data structure. I'm sure you believe that you already have such a pointer. But there's nothing in Lua that guarantees that the pointer you have obtained (through some means) is actually a pointer to the table data structure. It could be a pointer to something else. So you need to hunt through Lua's internals to make sure that wherever you're getting this pointer from is giving you a pointer to the actual object.
Find the correct type, declared within Lua's internals. There is some C type (Lua's written in C, not C++) that Lua uses to represent the main table data structure. You will have to track down this struct definition and use that.
A cursory examination of the Lua library suggests that the main table data structure is defined in lobject.h, under the name Table.
Find the internal APIs that Lua uses to manipulate this table correctly. It's obviously some kind of hash table, but you're going to need to use Lua's functions to actually do anything with it.
A cursory examination of Lua's internals suggests that this code would be found in ltable.h. However, there are probably more APIs than that. Also, do note that many of those APIs take a lua_State, so they may be doing some stack fiddling.
You will also need to look through Lua's API so that you can learn how to use them without breaking the table. Lua may have certain expectations about when certain functions are called or the order between them or whatever. Break these at your own peril.
Even then, this:
Table tab = *(Table*)0xaddr
Will never work. Or at least, not the way you mean for it to. Lua is written in C. Which means that Table is not going to work like a C++ value type. Copying it will only do a bitwise copy. So modifying tab will only modify your local copy of those values. If those are pointers to other data structures, that may be OK, since your pointers and the original pointers point to the same data structures. But if you perform some operation that changes the Table::flags field on the table, for example, the table stored in Lua will not be affected, only your local tab copy will be.
You have to manipulate the object as a pointer, not a copy of the original.
Table *tab = reinterpret_cast<Table*>(0xaddr);

Can you cast an address to an object instance in vb.net?

I'm exploring various ways to do c++, vb.net fused projects. What I love about c++ is that you can load up a bunch of binary data, give it a pointer with the appropriate type and bam! You have yourself a pod object instance.
I'm looking a way to do the same in vb.net but I'm rather fuzzy on the way vb.net handles its memory. Basically, is there a way to convert binary data into an object without too much overhead in a manner that the exact same data would also be viable in c++ and its equivalent class definition? Further more, could you do that to binary data in another processes memory or perhaps shared memory without moving the actual data? (so that if both c++ and vb.net programs object instances point to the same chunk of memory, if one changes the data, the other one is instantly up to date too)

CFile writing question

In my MFC application, I am using CFile class to write data to file. I store a sequence of objects of class CParagraph using Write() method for each data member in order. I use then Read() method to read from file into memory. One of the CParagraph's members used to be of type int, but now I have to change it to size_t, as int cannot hold data large enough. If my application reads a file created before this change, and then a saves a CParagraph object back into the file, size of size_t will be passed to the Write method instead of size of int, so the file will grow. My question is this: can the data written after the object being modified and saved be overwritten and thus corrupted because the object became larger ?
Thanks.
Yes. If anything in the file changes size, everything after it must be re-saved.
It's common to save a "version" char as the first part of a file. Then, when you need to resize a variable (or change tons of things), you can change the version when saving. Then, while loading, you can check the version, and use the coresponding code to load it. Then you can still open files from older versions. Note that this version should only change when the file format changes, not when you rebuild/release.

File operation in C++

I have written an object to file but when I read the object from the file, it is not getting the correct value. If 1 object is considered as 1 record and if only 1 record is there in the file, it's getting the value. If I write more records (many objects of the same type) then it's not getting the value.
There could be a couple of problems. Of the top of my head it might be an issue with how you are interfacing with the file, as the comments above indicate. Or it might be a serialization issue.
I recently learned that one cannot simply write a class to a file because its not guaranteed to be contiguous memory (other reasons too, but the moral I took was don't do it).
Instead one needs to serialize the object/class before writing it to the file.
A couple of web resources that I found useful for this are:
http://functionx.com/cpp/articles/serialization.htm (I liked this one a lot).
http://functionx.com/cpp/articles/serialization.htm
Is it possible to serialize and deserialize a class in C++?

C++ Storing objects in a file

I have a list of objects that I would like to store in a file as small as possible for later retrieval. I have been carefully reading this tutorial, and am beginning (I think) to understand, but have several questions. Here is the snippet I am working with:
static bool writeHistory(string fileName)
{
fstream historyFile;
historyFile.open(fileName.c_str(), ios::binary);
if (historyFile.good())
{
list<Referral>::iterator i;
for(i = AllReferrals.begin();
i != AllReferrals.end();
i++)
{
historyFile.write((char*)&(*i),sizeof(Referral));
}
return true;
} else return false;
}
Now, this is adapted from the snippet
file.write((char*)&object,sizeof(className));
taken from the tutorial. Now what I believe it is doing is converting the object to a pointer, taking the value and size and writing that to the file. But if it is doing this, why bother doing the conversions at all? Why not take the value from the beginning? And why does it need the size? Furthermore, from my understanding then, why does
historyFile.write((char*)i,sizeof(Referral));
not compile? i is an iterator (and isn't an iterator a pointer?). or simply
historyFile.write(i,sizeof(Referral));
Why do i need to be messing around with addresses anyway? Aren't I storing the data in the file? If the addresses/values are persisting on their own, why can't i just store the addresses deliminated in plain text and than take their values later?
And should I still be using the .txt extension? < edit> what should I use instead then? I tried .dtb and was not able to create the file. < /edit> I actually can't even seem to get file to open without errors with the ios::binary flag. I'm also having trouble passing the filename (as a string class string, converted back by c_str(), it compiles but gives an error).
Sorry for so many little questions, but it all basically sums up to how to efficiently store objects in a file?
What you are trying to do is called serialization. Boost has a very good library for doing this.
What you are trying to do can work, in some cases, with some very important conditions. It will only work for POD types. It is only guaranteed to work for code compiled with the same version of the compiler, and with the same arguments.
(char*)&(*i)
says to take the iterator i, dereference it to get your object, take the address of it and treat it as an array of characters. This is the start of what is being written to the file. sizeof(Referral) is the number of bytes that will be written out.
An no, an iterator is not necessarily a pointer, although pointers meet all the requirements for an iterator.
Question #1 why does ... not compile?
Answer: Because i is not a Referral* -- it's a list::iterator ;; an iterator is an abstraction over a pointer, but it's not a pointer.
Question #2 should I still be using the .txt extension?
Answer: probably not. .txt is associated by many systems to the MIME type text/plain.
Unasked Question: does this work?
Answer: if a Referral has any pointers on it, NO. When you try to read the Referrals from the file, the pointers will be pointing to the location on memory where something used to live, but there is no guarantee that there is anything valid there anymore, least of all the thing that the pointers were pointing to originally. Be careful.
isn't an iterator a pointer?
An iterator is something that acts like a pointer from the outside. In most (perhaps all) cases, it is actually some form of object instead of a bare pointer. An iterator might contain a pointer as an internal member variable that it uses to perform its job, but it just as well might contain something else or additional variables if necessary.
Furthermore, even if an iterator has a simple pointer inside of it, it might not point directly at the object you're interested in. It might point to some kind of bookkeeping component used by the container class which it can then use to get the actual object of interest. Fortunately, we don't need to care what those internal details actually are.
So with that in mind, here's what's going on in (char*)&(*i).
*i returns a reference to the object stored in the list.
& takes the address of that object, thus yielding a pointer to the object.
(char*) casts that object pointer into a char pointer.
That snippet of code would be the short form of doing something like this:
Referral& r = *i;
Referral* pr = &r;
char* pc = (char*)pr;
Why do i need to be messing around
with addresses anyway?
And why does it need the size?
fstream::write is designed to write a series of bytes to a file. It doesn't know anything about what those bytes mean. You give it an address so that it can write the bytes that exist starting wherever that address points to. You give it a size so that it knows how many bytes to write.
So if I do:
MyClass ExampleObject;
file.write((char*)ExampleObject, sizeof(ExampleObject));
Then it writes all the bytes that exist directly within ExampleObject to the file.
Note: As others have mentioned, if the object you want to write has members that dynamically allocate memory or otherwise make use of pointers, then the pointed to memory will not be written by a single simple fstream::write call.
will serialization give a significant boost in storage efficiency?
In theory, binary data can often be both smaller than plain-text and faster to read and write. In practice, unless you're dealing with very large amounts of data, you'll probably never notice the difference. Hard drives are large and processors are fast these days.
And efficiency isn't the only thing to consider:
Binary data is harder to examine, debug, and modify if necessary. At least without additional tools, but even then plain-text is still usually easier.
If your data files are going to persist between different versions of your program, then what happens if you need to change the layout of your objects? It can be irritating to write code so that a version 2 program can read objects in a version 1 file. Furthermore, unless you take action ahead of time (like by writing a version number in to the file) then a version 1 program reading a version 2 file is likely to have serious problems.
Will you ever need to validate the data? For instance, against corruption or against malicious changes. In a binary scheme like this, you'd need to write extra code. Whereas when using plain-text the conversion routines can often help fill the roll of validation.
Of course, a good serialization library can help out with some of these issues. And so could a good plain-text format library (for instance, a library for XML). If you're still learning, then I'd suggest trying out both ways to get a feel for how they work and what might do best for your purposes.
What you are trying to do (reading and writing raw memory to/from file) will invoke undefined behaviour, will break for anything that isn't a plain-old-data type, and the files that are generated will be platform dependent, compiler dependent and probably even dependent on compiler settings.
C++ doesn't have any built-in way of serializing complex data. However, there are libraries that you might find useful. For example:
http://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/index.html
Did you have already a look at boost::serialization, it is robust, has a good documentation, supports versioning and if you want to switch to an XML format instead of a binary one, it'll be easier.
Fstream.write simply writes raw data to a file. The first parameter is a pointer to the starting address of the data. The second parameter is the length (in bytes) of the object, so write knows how many bytes to write.
file.write((char*)&object,sizeof(className));
^
This line is converting the address of object to a char pointer.
historyFile.write((char*)i,sizeof(Referral));
^
This line is trying to convert an object (i) into a char pointer (not valid)
historyFile.write(i,sizeof(Referral));
^
This line is passing write an object, when it expects a char pointer.