Visual C++ Library Independence

Hello,

I'm a final year applied math student. My research project involves writing a C++ program to run simulations on multiple computers. I am using Visual Studio 2010. I'm also using the Boost library for random number generation. The compiled .exe file works perfectly on my computer but will not work on any other computer. I don't know much about programming but my best guess is that the .exe file is still dependent on the actual Boost library files. I'd like to put EVERYTHING into the .exe file as it compiles so that it becomes completely independent. I will run it on many many computers and I don't want to download and unzip Boost for all of them. I may be completely wrong, of course, and the reason might be different. So you seeing the code might help:

#include <iostream>
#include <ctime>
#include <new>
#include <limits.h>
#include <math.h>
#include <boost/random.hpp>

using namespace std ;

double rand_unif() ;
double rand_exp(double lambda) ;
bool is_finite(double x) ;

int main ()
{
// This is the underlying integer random number generator
boost::mt19937 igen;
// The second template parameter is the actual floating point
// distribution that the user wants
boost::variate_generator<boost::mt19937, boost::normal_distribution<> >
norm_dist(igen, boost::normal_distribution<>(5.0,0.001));

boost::variate_generator<boost::mt19937, boost::exponential_distribution<> >
exp_dist(igen, boost::exponential_distribution<>(100.0));

int i, j, ROWS, COLS, seed = time(NULL) ;
bool display, inf = false ;
double lambda = 1 ;
char filler ;

//inf = false ;

cout << "Input the number of rows: " ;
cin >> ROWS ;
cout << "Input the number of columns: " ;
cin >> COLS ;
display = ROWS*COLS <= 64 ;

double **grid = 0 ;
double *new_row = 0 ;
double *old_row = 0 ;
double *final_col = 0 ;

//memory allocated for 1st dimension.
grid = new double *[ROWS] ;
new_row = new double [COLS] ;
old_row = new double [COLS] ;
final_col = new double [ROWS] ;

//memory allocated for 2nd dimension (grid only).
for(i = 0 ; i < ROWS ; ++i) grid[i] = new double [COLS] ;

//set seed
srand((unsigned int) seed) ;

//fill the grid with random numbers
for (i = 0; i <= ROWS - 1; ++i){
for (j = 0; j <= COLS - 1; ++j){
grid[i][j] = exp_dist() ;

if (display) cout << grid[i][j] << " " ;
}
if (display) cout << endl ;
}

//initialize old_row and compute its values
for (i = 0; i <= COLS - 1; ++i) old_row[i] = grid[0][i] ;
for (i = 1; i <= COLS - 1; ++i) old_row[i] = old_row[i] + old_row[i-1] ;
final_col[0] = old_row[COLS - 1] ;

//loop through the rows
for (i = 1; i <= ROWS - 1; ++i){
new_row[0] = old_row[0] + grid[i][0] ;

//within each row, go through each element
for (j = 1; j <= COLS - 1; ++j) new_row[j] = grid[i][j] + max(new_row[j-1],old_row[j]) ;

//record the last value of each row as it is a part of the final column
final_col[i] = new_row[COLS - 1] ;

//old_row := new_row
for (j = 0; j <= COLS - 1; ++j) old_row[j] = new_row[j] ;
}

//output last passage time
cout << "Last passage time: " << old_row[COLS - 1] << endl ;

//clean up, end program
for(i = 0 ; i < ROWS ; ++i) delete [] grid[i] ;
delete [] grid ;
delete [] old_row ;
delete [] new_row ;
delete [] final_col ;
cout << "Cleaned up, ready to terminate\n" ;
cin >> filler ;
return 0 ;
}

double rand_unif(){
return (rand() + 1) / double((RAND_MAX + 1)) ;
}

double rand_exp(double lambda){
return -log(rand_unif())/lambda ;
}

bool is_finite(double x){
return (x <= DBL_MAX && x >= -DBL_MAX) ;
}

Any help would be much appreciated. Thank you :)
Last edited on
The compiled .exe file works perfectly on my computer but will not work on any other computer.
Do you mean any other Windows computer? What version of Visual Studio are you using and what OS did you build it on, and what OS will it not run on? Are either 32-bit/64 bit? What did you build it as?
All the computers use 32 bit, Windows XP Professional.

EDIT: I'm not sure what do you mean by "what did I build it as". Is this setting always the same as your OS (32 bit in this case) or can it be different? If it may be different, I don't know what I set it as so how can I check?
Last edited on
Sounds like you want what's known as "static linking", which will rely on the Boost static libraries being available at link-time (i.e. when building). Hopefully that's enough to get you moving :)
Last edited on
> I'm also using the Boost library for random number generation. ...
> ... but my best guess is that the .exe file is still dependent on the actual Boost library files.

No. Boost.Random, like the vast majority of Boost libraries, is a 'header only' library.

Perhaps you are linking to the DLL version of the MSVC run-time library, and MSVCR100.DLL or MSVCR100D.DLL are not available on the target machines. If that is the case, link to a static version of the MSVC run-time library and the problem will go away.
http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx

No. Boost.Random, like the vast majority of Boost libraries, is a 'header only' library.

Perhaps you are linking to the DLL version of the MSVC run-time library, and MSVCR100.DLL or MSVCR100D.DLL are not available on the target machines. If that is the case, link to a static version of the MSVC run-time library and the problem will go away.
http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx

Sorry I don't really understand the page you've just linked me to... How exaxtly does one use those options in the Visual Studio Command Prompt? Also, I don't know if this matters, but looking in the actual unzipped Boost folder that I linked to I see no DLL files, nor do I see any DLL files in the project folder of my code.
> Also, I don't know if this matters, but looking in the actual unzipped Boost folder that I linked to I see no DLL files,
> nor do I see any DLL files in the project folder of my code.

No, it does not matter. Boost.Random does not require any libraries.


> How exaxtly does one use those options in the Visual Studio Command Prompt?

To set this compiler option in the Visual Studio development environment

Open the project's Property Pages dialog box. For details, see How to: Open Project Property Pages.

Click the C/C++ folder.

Click the Code Generation property page.

Modify the Runtime Library property.



/MT
Causes your application to use the multithread, static version of the run-time library. Defines _MT and causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols.

/MTd
Defines _DEBUG and _MT. This option also causes the compiler to place the library name LIBCMTD.lib into the .obj file so that the linker will use LIBCMTD.lib to resolve external symbols.


http://msdn.microsoft.com/en-us/library/610ecb4h.aspx
I tried the /MT and /MTd settings and tried rebuilding the solution as I usually do. The /MT couldn't compile due to errors and the /MTd compiled fine and it worked on other computers! I'm not sure if this is what you were getting at and how acceptable it is (maybe it "works" in my understanding but it's actually completely wrong to do it this way). But in my very limited understanding of what's happening the problem appears to be solved.

Thank you very much for your patience and help - it's never easy explaining stuff so someone who has no understanding of the subject!

Can I ask one more question please: I used the "time(NULL)" function to get a different seed hence a different random sequence every time for my own exponential distribution. But how do I do the same for the Boost code that I am currently using?

My random code:

//DECLARATIONS in MAIN:
int i, j, ROWS, COLS, seed = time(NULL) ;

//GETTING THE GENERATOR GOING FROM THE SEED:
srand((unsigned int) seed) ;

//FUNCTIONS:
double rand_unif(){
return (rand() + 1) / double((RAND_MAX + 1)) ;
}

double rand_exp(double lambda){
return -log(rand_unif())/lambda ;
}



The new Boost code:

// This is the underlying integer random number generator
boost::mt19937 igen;
// The second template parameter is the actual floating point
// distribution that the user wants
boost::variate_generator<boost::mt19937, boost::normal_distribution<> >
norm_dist(igen, boost::normal_distribution<>(5.0,0.001));

boost::variate_generator<boost::mt19937, boost::exponential_distribution<> >
exp_dist(igen, boost::exponential_distribution<>(100.0));


With me using "norm_dist()" to get a normally distributed random number

Thank you!
Last edited on
you probaly compile your project as debug. Change the configuration to release. Because VC++ is installed on your computer the debug versions of the dll are available while most other computer not.
> The /MT couldn't compile due to errors and the /MTd compiled fine and it worked on other computers!

The /MT option is for the release version of the library and the /MTd is for the debug version.


> I'm not sure if this is what you were getting at and how acceptable it is

This was what I was getting at. However, I would recommend performing a Release build with /MT for redistributing your program (without dll dependencies) on other computers.


> I used the "time(NULL)" function to get a different seed ...
> ... how do I do the same for the Boost code that I am currently using?

1
2
// boost::mt19937 igen;
boost::mt19937 igen( std::time(0) ) ; 

Pardon for the previous post, I was messing up very simple things. Once I set the Release option, it immediately underlines everything to do with Boost in red and doesn't compile:
1>------ Rebuild All started: Project: test1, Configuration: Release Win32 ------
1> testing_ground_1.cpp
1>testing_ground_1.cpp(7): fatal error C1083: Cannot open include file: 'boost/random.hpp': No such file or directory
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Why is this error happening? Should I change my "#include" statement in any way?
You haven't set up the include paths for Release, you need to copy over the setting from Debug.
Ah, didn't realise that setting to Release nullifies your include selections.

It all works now! Thank you very much everyone! :)
Topic archived. No new replies allowed.