Suppose I have built a lot of dlls from a certain revision of the svn repository. (It might by any revisioning system)
I am able to create a resource file containing an entry that denotes the revision number.
Can I link that resource file into the dll's I have already built? Some sort of editbin or the like?
You can write a small program to do this, using the UpdateResource function in Windows NT:
http://msdn.microsoft.com/en-us/library/ms648049(v=VS.85).aspx
The resource compiler uses the C pre-processor. You can simply use a #define in a header file you #include in your .rc file. Or use the /D command line option for rc.exe. You can use the macro symbol in your resource definition.
Related
Now I am building a .dll project with VC 10. Depending on whether certain libraries are included or not, the output .dll as well as its corresponding lib file names should be different. For example, if the project uses the native STL library provided by Mirosoft, the .dll name is *_native_stl.dll; if the project uses STLport, then the output .dll name is *_stlport.dll. Of course I can do it manually, but I am now considering to let VC 10 do it for me automatically. My plan is that if I use a certain library, I define a variable to represent it in the Preprocessor Definitions (located in C/C++ Preprocessor)section. After that, I define a .bat file in the Post-Build Event (located in Build Events) section: call "$(ProjectDir)\script.bat". In the script.bat file, I will changed the default .dll output name $(OutDir)$(TargetName)$(TargetExt) according to the variable definition in the Preprocessor Definitions section. My main problem is that for in batch file how I can check a certain variable is defined or not. Thanks! Any suggestions on changing output file name are welcome as well.
My main problem is that for in batch file how I can check a certain variable is defined or not. Thanks!
You can check this with a statement like this:
if "%MYVAR%" == "" set undefined=1
The variable undefined will be set to 1 only if MYVAR is not defined.
I'm porting a C++ application from Unix and the original developer created several files with main() functions, then use Makefile to choose which main() to use.
How do choose which file contains the main() function in Visual C++ 2010?
Currently, when I compile I get a linker error due to duplicate main() symbols.
The only thing I can think of is macro conditional.
Any other ideas?
Multiple main functions mean that the original code does not create a single executable, but rather a set of them. You should figure out what parts belong to each one of the executables (read the Makefile) and then create different projects inside the solution one for each one of the executables (do the same for the libs). Then you can use the IDE to select which executable you want to compile/run.
in the Configuration Properties for each source file (right-click in Solution Explorer) you can select 'Excluded From Build'. As this is a per-configuration setting, you can add some configurations and mutually exclude the files with main(). For instance for configuration 'MainA' you include maina.cpp and exclude mainb.cpp and mainc.cpp, for 'MainB' include mainb.cpp and exclude maina.cpp and mainc.cpp, etc.
Another option would be to have only one main() and select the appropriate source using arguments or a configuration file. Or, maybe the best solution, create one project for each main file and put the common parts in a static or shared library.
One source with multiple objects
I am using MSVS 2010 and I have a C++ source-file which must compile into 2 object-files.
The diiference between those compilations is a "#define UNICODE" for one of them but not for the other.
I can't (and don't want to) use templates for a this.
Currently ,I use 3 source files for this in my project.
The actual source is excluded from build ,while the other 2 are wrappers around it.
Like this :
file = wrap-UNICODE.cpp
#ifndef UNICODE
#define UNICODE
#endif
#include "actual-source.cpp"
// eof
file = wrap-ANSI.cpp
#ifdef UNICODE
#undef UNICODE
#endif
#include "actual-source.cpp"
// eof
When using makefiles i can easily avoid the use of wrapper soucrces ,using different output
switches.
My question is ,I would like to know if (and how) i can do this directly in a MSVS project.
If i correctly understand what you want to do, this is possible.
I have MS Visual Studio 2005 Standard Edition; here is how i can do this (you might have to adjust this if you have a different version, or possibly it might even not work in your version; i hope your computer doesn't explode :) ).
The first step requires manual editing of the project file. Open the project file (it is called stuff.vcproj on my machine) and replicate the lines that mention your file:
<File
RelativePath=".\actual-source.cpp"
>
</File>
<File
RelativePath=".\actual-source.cpp"
>
</File>
Then, load the project into MSVS. Go to the Solution Explorer (Ctrl+Alt+L on my machine); the project will show two files with identical name. Open the Property Pages of each one (Alt+F7 on my machine) and add any differences you want (e.g. Preprocessor Definitions).
You must also set different names for object files: choose Output Files, Object File Name in the same window (Property Pages), and add different names (e.g. actual-source-unicode; MSVS will add the .obj extension when compiling). If you don't do that, the two obj-files will have the same name, and one will overwrite the other.
AFAIK you can create multiple builds in your solution. Just go in the configuration manager of the solution (should be accessible from contextual menu on the solution).
In this way you can also avoid to have two versions of your file. It is sufficient to set the define options differently in the two configurations.
Visual Studio defines _UNICODE for you if you intend to build unicode apps.
Why don't you simply use different configurations for your two builds (as Luca Martini mentions) and then use Batch Build? You can then compare the compiled outputs any way you want.
I am using #define and #ifndef to strip down the exe size, i noticed the resource.h and icon.ico files eat a lot of space, so i would like to not include those in my exe at all.
How do i add rule for this that obeys my #define commands ? I could edit the resource.h, but every time i change it, it would get overwritten by Visual Studio.
Edit: i dont know what is the correct name for these resource things, but my "resource.h" includes the window menu option stuff etc.
How much is "a lot of space" that you speak of?
resource.h is used for #define-ing constants that identify resources, e.g. they're just numbers. They shouldn't be a factor in executable size.
What is a factor in executable size is the resources that you embed in the executable, specified by a *.rc file. icon.ico takes up space in the *.exe because the compiler embeds the binary of the icon into the executable file itself. This icon is specified in an *.rc file that should be somewhere in your project.
You can choose to remove the icon from the *.rc file and store it separately from the *.exe file, but it's easier to just embed it into the executable. The information for defining menus, icons, dialogs, etc. has to be stored somewhere, after all.
Edit: You can have multiple resource files, so Visual Studio doesn't overwrite your directives. Refer to http://msdn.microsoft.com/en-us/library/6t3612sk(v=VS.80).aspx to see how Visual Studio handles multiple resource files. The section called "Using Multiple Resource Files in the Same Project" seems to be relevant to your problem.
In VS2010, properties for icon resources include an item "Condition" which is described as "Specifies the preprocessor symbol that determines the inclusion of the resource".
Can you upgrade?
The edit window is disabled though, you have to jump through some hoops to set the Condition. Right-click the resource and choose "Insert Copy", then you can set the condition, then delete the original unconditional icon.
Maybe this trick would work in VS2008 as well, don't have it installed on this computer so I can't test it.
My project is set up so all the framework code and modules are compiled to a static .lib (let's call it framework.lib), and many test projects use framework.lib and compile to executable files.
For error handling, I'm trying to put the resource strings in framework.rc (part of the framework.lib project) and load the strings in the executable files. However, LoadString() just fails. Using GetLastError() / FormatMessage() I get the following message:
"The specified resource type cannot be found in the image file."
Here is how I call LoadString, which returns 0:
char szString[256];
int iNbOfChars = LoadStringA(GetModuleHandle(NULL), iStringID, szString, 256);
Should what I do be failing because the resource is not defined in the app, but in the lib? If so, any suggestions so I can have a centralized resource file?
Static libraries are just concatenations of .OBJ files - they don't have features like resources. To do this you need to put the resources in DLL.
You can't put resources into .lib files. (I wish you could). You have to keep the .rc files around and include them into the app's .rc file when you link to the lib.
And because of that, you have to make sure that none of the resource id's used by the .lib are also used by the app. It's a whole mess, but there is no better solution if you use .rc files for your strings. and stick with microsoft's tools.
About couple of years ago I got so frustrated with this limitation, that I went off and build a tool that would turn a compiled resource file (.res) into a .obj file, so I could include it into my lib. Of course, when you do that, you can't use LoadString anymore, but it turns out that writing your own code to parse a hunk of .res data and find the strings isn't really that hard. So my current solution to put strings in libraries is
create framework.rc
compile it into framework.res
turn framework.res into framework.obj which contains external symbols
const BYTE framework_res[];
const size_t framework_res_size;
use MyLoadString(framework_res, framework_res_size, iStringId, sz, 256) instead of LoadString when fetching strings in the library.
One advantage of doing it this way turned out to be that when I wrote my own LoadString, I could return a pointer to the resource string, rather than copying it. so my actual LoadString function looks like this.
LPCWSTR MyFindString(framework_res, framework_res_size, iStringId);
If you compile your .rc file with the /n option, it will null terminate all of the strings.
You can use an #include directive in the app's resource file to include the lib's resource file.
Resources are only allowed at the output (EXE) level and cannot be embedded into a .Lib.
AFAIK you can not add resources to a static library - you have to either compile them into a DLL to share or directly into the Application.
You could share the .rc from a central location and compile that into the application itself.
The obvious way to centralize the resources would be to create a DLL that contains the resources. Then you can use LoadString and such just like if the resource was in the executable, except for the minor detail that you need to specify the correct module handle instead of NULL.