Static library vs Dynamic library for storing classes - c++

I was storing my classes in static libraries.For example modify the original header file like adding line pragma comment(lib,"MyClass") then copy files to the visual studio's include and lib folder.Whatever everything was fine until i wanted to add Menu to my class.Lib files does not have resources so i am going to use dynamic link library for this class.Is this logical that storing classes in dlls? also i dont know how to use dlls like that...
is there some examples for this? Also there is classes like CFileDialog that have resources(dialog) this kind of classes use static libraries or dynamic ?

To me, this sounds like "the wrong place to split things". In other words, if your library needs a resource that is part of the application, then it's probably not meant to be a library in the first place - it is either a proper standalone DLL that contains its own resource, because it has a complete and standalone functionality, or it's actually part of the main executable, and uses the main executable's resource.
The point of making something into a library is that it allows the separation of the library contents from the main application.
Another option is of course that you pass in the relevant resource information from the main application to your class in the library [this works for a a DLL too, of course].
My point here is that a menu is something that belongs to the main application - it knows what it has under File, Edit, View, etc. If you are writing a word processor, you may have things like "Spell checking" in there, but you don't want "Spell checking" in the Photo Editor software, but you probably want some way to get colour profile information to match the monitor's colour balance with the official colours. So your "class" to handle menus probably shouldn't "know" what the menus are, but just how to deal with menus in general - what menus you have comes from the actual main application.
I know this isn't really a direct answer to your questions...

Related

Methods for opening a specific file inside the project WITHOUT knowing what the working directory will be

I've had trouble with this issue across many languages, most recently with C++.
The Issue Exemplified
Let's say we're working with C++ and have the following file structure for a project:
("Project" main folder with three [modules, data, etc] subfolders)
Now say:
Our maincode.cpp is in the Project folder
moduleA.cpp is in modules folder
data.txt is in data folder
moduleA.cpp wants to read data.txt
So the way I'd currently do it would be to assume maincode.cpp gets compiled & executed inside the Project folder, and so hardcode the path data/data.txt in moduleA.cpp to do the reading (say I used fstream fs("data/data.txt") to do so).
But what if the code was, for some reason, executed inside etc folder?
Is there a way around this?
The Questions
Is this a valid question? Or am I missing something with the wd (working directory) concept fundamentals?
Are there any methods for working around absolute paths so as to solve this issue in C++?
Are there any universal methods for doing the same with any language?
If there are no reasonable methods, how would you approach this issue?
Please leave a comment if I missed any important details with the problem's illustration!
At some point the program has to make an assumption where the file(s) are. Either by getting it from user input or a relative path with the presumed filename. As already said in the comments, C++ recently got std::filesystem added in C++17 which can help you making cross-platform code that interacts with the hosts' filesystem.
That being said, every program, big or small, has to make certain assumptions at some point, deleting or moving certain files is problematic for any program in case the program requires them to be at a certain location under a certain name. This is not solvable other than presenting the user with an error message etc.
As #Hatted Rooster said, it's not generally solvable for some arbitrary file without making some assumptions, however there are frameworks that allow you to "store" some files in the resources embedded into the executable (or otherwise). Those frameworks would usually allow your to handle such files in a opaque way, without the need to rely on a current working dir or relative paths.
For example, see the Qt Resource System.
Your program can deduce the path from argv[0] in the main call, if you know that it is always relative to your executable or you use an absolute path like "C:\myProgram\data\data.txt".
The second approach works in every language.

Accessing the same object across multiple projects in a VC solution

I have a set of 30 variables that I need to be able to modify and use from within any of the 50 projects in my solution. Since, the variables happen to relate to the same entity, I would like to encapsulate them in a class. I plan to have only a single instance of the class. But I would like this instance to be accessible and modifiable from any of my 50 projects in the solution. Please tell me how.
You can create a static library project and use that to make your class.
As you build other apps (console projects i would guess) under project properties for the app, you should be able to add a reference to the library project. That gets you your link.
There would also need to be a way for the app to get to your class header file.
One way to do it would be to put the path in the include.
#include "c:\somesolution\common_library\common_class.hpp"
Another way to do it, would be to add the path to the library to your VC++ Directories for the app project.
Design the solution as a shared file. Then for a bit better performance you can map the file into shared memory.

Hiding application resources

I'm making a simple game with SFML 1.6 in C++. Of course, I have a lot of picture, level, and data files. Problem is, I don't want these files visible. Right now they're just plain picture files in a res/ subdirectory, and I want to either conceal them or encrypt them. Is it possible to put the raw data from the files into a resource file or something? Any solution is okay to me, I just don't want the files exposed to the user.
EDIT
Cross platform solutions best, but if they don't exist, that's okay, I'm working on windows. But I don't really want to use a library if it's not needed.
Most environments come with a resource compiler that converts images/icons/etc into string data and includes them in the source.
Another common technique is to copy them into the end of the final .exe as the last part of the build process. Then at run time, open the .exe as a file and read the data from some determined offset, see Embedding a filesystem in an executable?
The ideal way for this is to make your own archive format, which would contain all of your files' data along with some extra info needed to split files distinctly within it.

Is there any method to know whether a directory contain a sub directory?

I am woking in c++.
Is there any method to know whether a directory contain a sub directory?
CFileFind seems have to search through total files.
It is time consuming if the only subdirectory is at the end of the list and the there are lots of files.
for example: directory A contains 99995 files and one subdirectory at the end of FindNextFile List. had I try 99995 times, then say: yes, it contains subdirectory?
Raymond Chen from Microsoft has written a post that probably applies here: Computing the size of a directory is more than just adding file sizes. In essence, he explains that information like the size of a dir cannot be stored in the dir's entry, because different users might have different permissions, possibly making some of the files invisible to them. Therefore, the only way to get the size the user should see is to calculate it upon request from the user.
In your case, the answer probably stems from the same reasoning. The list of directories available to your app can only be determined when your app asks for it, as its view of the root directory might be different than another app's, running with different credentials. Why Windows store directories along with files I don't know, but that's a given.
Since Win32 is as close as you'll get to the file system in user mode, I'd avoid any higher level solutions such as .NET, as it might only simplify the interface. A driver might work quicker, but that out of the scope of my knowledge.
If you are using the .Net framework you could use Directory.GetDirectories and check is the size of the array is 0. Do not know how if this will give you speed.
If you have control over the directories you could apply a naming convention so that directories that have sub directories are named one way and directories with out sub directories are named another.
You can try using the boost filesystem library.
A class by name directory_iterator [ declared in boost/filesystem/operations.hpp ] has many functions which can be used for listing files, finding whether the file is a sub-directory ( is_directory -- I guess this is what you are looking for ) etc..
Refer the following link for more information.
link text
It seems you are using MFC [ just saw that you are using CFileFind ], didn't see that earlier.
Sorry, Didn't have much info. You may have to use FindFirstFile/FindNextFile.
Whether this can be done very fast is entirely platform-dependent.
On Win32 you use FindFirstFile/FindNextFile or wrappers on top of those like MFC CFileFind and they list items in some order that can't be forced to list directories first.

Can I use two incompatible versions of the same DLL in the same process?

I'm using two commercial libraries that are produced by the same vendor, called VendorLibA and VendorLibB. The libraries are distributed as many DLLs that depend on the compiler version (e.g. VC7, VC8). Both libraries depend on a another library, produced by this vendor, called VendorLibUtils and contained in one DLL.
The problem: VendorLibA uses a different version of VendorLibUtils than VendorLibB. The two versions are not binary compatible, and even if they were it would be a bad idea to use the wrong version.
Is there any way I could use the two libraries under the same process?
Note: LoadLibrary can't solve this since my process is not that one that's importing VendorLibUtils.
EDIT: Forgot to mention the obvious, I don't have to source code for any of the commercial libraries and probably I will never have (sigh).
EDIT: The alternative btw, is to do this: How to combine GUI applications in Windows
I think your most promising option is to complain, loudly, to the vendor who is distributing mutually incompatible products. That rather goes against the idea of a DLL.
You can't just put the DLLs in different directories. Once a DLL with a given name is loaded, all other attempts to load another DLL with the same module name will simply use the one that's already loaded, even if the paths are different.
From that, we can conclude that to load two copies of VendorLibUtils, one copy needs to have a different name. You can't just rename the DLL file; the code in your program won't know to look for the different file. Therefore, perhaps there's a way to edit the import table of VendorLibB to make it think the functions it needs are in VendorLibUtilsB.dll instead of just VendorLibUtils.dll. I'm afraid I don't know of any utility that will do that, but I have little doubt it's possible to do.
I had a similar problem. Specifically I wanted to use a PyQt from a Python interpreter embedded in an application that was using an incompatible version of Qt. There were two Qt DLLs used by the primary application: QtCore.dll and QtGui.dll.
When I would load PyQt from the embedded Python interpreter, I would get an error:
ImportError: DLL load failed: The specified procedure could not be found.
This occured on the line:
from PyQt4 import QtGui
The problem is that the once an incompatible QtGui.dll is loaded into the main application's process space any references to QtGui.dll (e.g. from the file QtGui.pyd) are incorrect.
What happened next, I am not proud of.
First I renamed QtGui4.dll in the PyQt distribution to QtGuiX.dll
and then renamed the QtCore4.dll to QtCoreX.dll. Notice that the
renaming maintained the same number of characters, this is important.
Next I opened the file QtGui.pyd in Notepad++, and replaced all
plain-text references of QtGui4.dll to QtGuiX.dll and from
QtCore4.dll to QtCoreX.dll. I repeated the process for the files:
QtCore.pyd, QtGuiX.dll and QtCoreX.dll.
Finally I checked that my PyQt test application still worked. It did!
Then I tried running the PyQt test application from the embedded
Python interpreter, and it worked as well.
So, it seems to works in a couple of trivial cases. I expect that I
need to repeat the process for all DLLs and PYDs in the PyQt
distribution.
This is probably not the right way to do things, but I can't think of any concrete reasons how it could blow up (other than if I change the length of the file name).
Credit (or blame) to others on the thread for inspiring this terrible tale.
As someone else mentioned, you could rename one of the copies of VendorLibUtils and modify the import table of the associated VendorLib DLL to link to it, rather than the VendorLibUtils.dll it was created with.
There's a few tools out there that let you edit EXE/DLL files in this way. CFF Explorer is a pretty decent one which allows editing of the import table. If you open up the VendorLib DLL in it and go to the Import Directory section (in the tree on the left), you'll see a list of modules at the top of the main window. You can rename the module by double-clicking on its name. Then you just save the DLL and it should now use your renamed VendorLibUtils DLL.
Of course, this assumes that VendorLib uses the import table to access VendorLibUtils, which it may not -- it may use LoadLibrary/GetProcAddress, in which case you won't see an import table entry for VendorLibUtils.
Actually, if the VendorLib does use the import table but also uses LoadLibrary to access the VendorLibUtils DLL in some places (I've seen it done), those places will still use the wrong one. If you rename both libraries, you might at least see an error if this is the case (since a DLL with the original name won't exist now). There is a way to deal with this if it occurs, but it starts to get quite complicated at this point, so I won't elaborate unless you really want/need to know.
As you are not using VendorLibUtils directly, I assume you can't use LoadLibrary etc.
If the VendorLibUtils DLLs only have exports by ordinal, you could probably rename one of the the libraries and patch the corresponding VendorLibX to use a different filename for its imports.
If the VendorLibUtils DLLs have one or more exported symbols with the same names, you might need to patch the imports and export tables too, but let's hope not! :-)
I'm no expert in DLLs, but the only way I see it possible would be to use LoadLibrary() and explicitly load the DLLs. Then you could place the functions/classes etc in separate namespaces using GetProcAddress().
HMODULE v1 = LoadLibrary(_T("libv1_0.dll"));
libv1_0::fun_in_lib = reinterpret_cast<FUNTYPE>(GetProcAddress(v1, _T("fun_in_lib"));
and
HMODULE v2 = LoadLibrary(_T("libv2_0.dll"));
libv2_0::fun_in_lib = reinterpret_cast<FUNTYPE>(GetProcAddress(v2, _T("fun_in_lib"));
Whether this would work or not still kind of depends on the library, so it may or may not work, but as far as I can tell it's the only possibility.
You mean, you have a situation similar to MSVCRT80.DLL and MSVCRT90.DLL ? There is a good reason Microsoft numbered these DLLs.If both were called MSVCRT.DLL, only one of them would be loaded in a single process.
It is actually possible to implicitly load different versions of a dll into a single process.
Doing this entails:
Creating two assemblies, each containing a version of the dll that must be loaded multiple times. Sounds complicated but practically it entails little more than creating (2) named sub folders, each with a .manifest file containing some xml, and its own copy of the dll. So, VendorUtilsAssemblyV1 and VendorUtilsAssemblyV2
Making each dependent dll use the assembly mechanism to resolve the implicit dependency - by adding a assemblyDependency directive that explicitly identifies VendorUtilsAssemblyV1 or V2.
There are some options for point 2. If the VendorLibA and VendorLibB files do not contain their own manifests, then you can simply add manifest files with the required dependentAssembly directive named VendorLibA.2.dll.manifest and VendorLibB.2.dll.manifest.
If they already contain manifests (probably to link to the VS2005 or VS2008 C-Runtime) then use the MT.EXE tool to merge in the new dependency.