Accessing text data files from a static library function - c++

How to I enable a static library to pull in data available in ascii data files?
I am trying to add a model to a simulation as a library which contains functions that read data from data files. I am able to compile and run the functions from a main program outside the actual full simulation, but once I put the functions as a library on the host for the simulation the data no longer gets read.
As the path to the data is changing depending on the user, I cannot provide an absolute data path to the ascii data files. Is there a way to use objcopy to make the data files into object code in the library or how can I best access the data from my static library?

There are several solutions to open a file that has an unknown location at compile time. Prompt the user for the name of the file, including directory. Use an environment variable to designate the directory containing the file ... Fortran 2003 has an intrinsic to obtain the value of an environment variable. Obtain the information from a command line argument ... again Fortran 2003 has an intrinsic for this purpose. With all of these, construct the filename as a string variable and provide that variable to the FILE keyword of the OPEN statement.

I don't know why you inclouded the Fortran tag, but in Fortran you:
tell the code to open a file you want using a character string
to read from it
and to close it
There is no difference between a main program or a library.

If you have a function like, say:
void read_data_from_files() { ... }
You'll need to change it in the DLL to be more like:
DataObject read_data_from_file(const char* file_path) { ... }
And then call it appropriately.
You'll need to design DataObject.

Related

File Type To Program Associations And File Location(Windows)

In Windows if I have a program association set to invoke my program to open/edit a data file with a specific extension, how will my program - once invoked - know the path and filename of the data file? Preferably solutions using batch, C++, or C. -Tom
Look at the command line arguments (i.e. %1, %2... for batch, argv[1]... for C++, C) - they should hold the path and name of the .gb file (or if there's no path, at least a name relative to the current working directory).

Correct way to extract array data from binary?

There is a classic way to embed resource files as a C language array into a binary file, so that we can store some external resource files such as .jpeg or .txt files into a binary.
For example, in the header file we can define an array:
const unsigned char xd_data[] = {
77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0,184,0,0,0,0,0,0,0,64,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,
0,14,31,186,14,0,180,9,205,33,184,1,76,205,33,84,104,105,115,32,112,114,
111,103,114,97,109,32,99,97,110,110,111,116,32,98,101,32,114,117,110,
32,105,110,32,68,79,83,32,109,111,100,101,46,13,13,10,36,0,0,0,0,0,0,
0,66,163,223,218,6,194,177,137,6,194,177,137,6,194,177,137,105,221,187,
137,13,194,177,137,133,222,191,137,3,194,177,137,105,221,181,137,4,194,
177,137,136,202,238,137,4,194,177,137,6,194,176,137,73,194,177,137,133,
202,236,137,13,194,177,137,48,228,187,137,11,194,177,137,193,196,183,
137,7,194,177,137,82,105,99,104,6,194,177,137,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,80,69,0,0,76,1,4,0,65,162,32,86,0,0,0,0,0,0,0,
0,224,0,47,1,11,1,6,0,0,100,0,0,0,74,0,0,0,0,0,0,228,113,0,0,0,16,0,0,
0,128,0,0,0,0,64,0,0,16,0,0,0,2,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
224,0,0,0,4,0,0,0,0,0,0,2,0,0,0,0,0,16,0,0,16,0,0,0,0,16,0,0,16,0,0,0,
0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,124,140,0,0,140,0,0,0,0,208,0,0,0,16,0
};
which contains the contents of the resource file, and it will be compile into the final binary.
There are lots of tools and tutorials on the web about this old trick, such as: http://www.rowleydownload.co.uk/arm/documentation/index.htm?http://www.rowleydownload.co.uk/arm/documentation/embed.htm, https://www.fourmilab.ch/xd/ and http://gareus.org/wiki/embedding_resources_in_executables#c_include_method.
However, looks like most of these pages are talking about how to embed the data into binary file using C style array.
My question is, what is the correct way to find the start address of the resource files in the compiled binary in order to extract them? I.e., how can I find the start address of xd_data in the compiled binary?
If you mean finding the byte address in the file where a data block starts just like objdump does but programmatically, then you can use the Binary File Descriptor library (BFD), see here and here.
if you stored data for example an image and you want to load it (for printing or what ever you want) then if you have a function (library) that load it from memory, as example void loadResImage(void * mem); just do loadResImage(xd_data), if not but you have a function that load it from the file, in that case save it to a temp file eg:
int fd=open("tmpfile");
int ret=write(fd,xd_data, sizeof(xd_data));
close(fd);
loadImageFile("tmpfile");
but if you want to access the data outside the program itself (hex editor for example, or an other program), in that case you have to add a starting mark and optionally an ending mark or sizeof data. eg:
const unsigned char xd_data[]={
...
'M','A','G','I','C'};
in example above the end of the data is known, you just do a search to find it. same way, play around and find a suitable way to store the size of the data. but beware of the compiler optimizations.

Ensure File Extension Matches File Type in C++

all. I am trying to write a C++ program that will iterate through a user-specified directory (e.g. /home/alpernick/Pictures). Primarily, this is to ensure that there are no duplicates (checked via md5sum).
But one feature I truly want to include is to ensure that the extension of a filename matches the file's type.
For example, if the file's name is "sunrise.png" I want to ensure that it actually is indeed a PNG and not a mislabeled JPEG (for example).
I am approaching this with four functions, as follows.
string extension(string fileName) // returns the extension of fileName (including .tar.gz handling, so it isn't blindly just returning the last 3 characters)
string fileType(string fileName) // This one is the key -- it returns the actual file type, so if the file named fileName is a PNG, fileType() will return PNG, regardless of the return value of extension()
string basename(string fileName) // Rerturns the basename of the file, I.e. everything before the extension (so, for sunset.jpg, it would return sunset; for fluffytarball,tar.gz, it would return fluffytarball)
string renameFile(string incorrectFileName, string fileNameBeforeExtension, string actualFileType) // Returns a string whose value is the basename concatenated with the correct file extension.
string file = sunset.jpg;
/* Setting file to be hard-coded for illustrative purposes only */
if(extension(file) != fileType(file)
{
char fixedName [] = renameFile(file, basename(file), fileType(file));
puts(fixedName);
}
I have zero issues with the string processing. I'm stuck, however, on fileType(). I want this program to not only run on my primary machine (Kubuntu 14.04), but also to be capable of being run on a Windows machine as well. So, it seems I need some library or set of libraries that would be common to both (or at the least compiled for both).
Any help/advice?
There are more exceptions than rules for guessing the actual type of a file based on its contents.
This is exacerbated by the fact that a file can be valid and useful interpreted as two completely different file types.
For a good program trying to guess on insufficient data, try file on Unixoids.
You could try looking at file source code: https://github.com/file/file .
But as wikipedia states
file's position-sensitive tests are normally implemented by matching various locations within the file against a textual database of magic numbers (see the Usage section). This differs from other simpler methods such as file extensions and schemes like MIME.
In most implementations, the file command uses a database to drive the probing of the lead bytes. That database is implemented in a file called magic, whose location is usually in /etc/magic, /usr/share/file/magic or a similar location.
So it does not seem trivial.

where to store .properties file for use in c++ dll

I created a .properties file that contains a few simple key = value pairs.
I tried it out from a sample c++ console application, using imported java classes, and I was able to access it, no problem.
Now, I am trying to use it in the same way, from a C++ dll, which is being called by another (unmanaged) c++ project.
For some reason, the file is not being accessed.
Maybe my file location is wrong. Where should I be storing it?
What else might be the issue?
TIA
As you are mentioning "DLL" i guess, that you are using MS Windows. Finding a file there from a DLL, and independently from the logged on user is a restricted item. The best way is to store the file in a path assembled from the environment variable ALLUSERSPROFILE. This is the only location that is equal to all users and where all users usually have write access. Your applications data should reside in a private subdirectory named like < MyCompany > or < MyApplicationsName >. Type
echo %ALLUSERSPROFILE%
on a windows command line prompt to find out the actual location on a machine.
Store your data in i.e.:
%ALLUSERSPROFILE%\MyApp\
Your dll can then query the location of ALLUSERSPROFILE using getenv:
char *allUsersData = getenv("ALLUSERSPROFILE");

Embedding a file into a program

I want to embed a file in a program. It will be used for default configuration files if none are provided. I have realized I could just use default values, but I want to extract the file and place it on the disk so it can be modified.
By embedding do you mean distributing your program without the file?
Then you can convert it to configuration initialization code in your build toolchain. Add a makefile step (or whatever tool you're using) - a script that converts this .cfg file into some C++ code file that initializes a configuration data structure. That way you can just modify the .cfg file, rebuild the project, and have the new values reflected inside.
By the way, on Windows, you may have luck embedding your data in a resource file.
One common thing you can do is to represent the file data as an array of static bytes:
// In a header file:
extern const char file_data[];
extern const size_t file_data_size;
// In a source file:
const char file_data[] = {0x41, 0x42, ... }; // etc.
const size_t file_data_size = sizeof(file_data);
Then the file data will just be a global array of bytes compiled into your executable that you can reference anywhere. You'll have to either rewrite your file processing code to be able to handle a raw byte array, or use something like fmemopen(3) to open a pseudo-file handle from the data and pass that on to your file handling code.
Of course, to get the data into this form, you'll need to use some sort of preprocessing step to convert the file into a byte array that the compiler can accept. A makefile would be good for this.
Embedded data are often called "resources". C++ provides no native support, but it can be managed in almost all executable file formats. Try searching for resource managers for c++.
If it's any Unix look into mapping the file into process memory with mmap(2). Windows has something similar but I never played with it.