Using a variable across c++ programs (compilations) - c++

this type of question has been asked several times over here and elsewhere but it seems that I don't get any of the solutions to work. What I've 'accomplished' so far is that a variable can be used by two different applications (one application calls the other one via system command) but the value is NOT passed from the main app to the secondary one.
code corresponds to this:
#ifndef avis_h
#define avis_h
#include "string"
using namespace std;
extern int fnu;
#endif
that's the header file avis_h.
The main program goes like this:
#include "stdafx.h"
...
#include "iostream"
#include "avis_h.h"
int fnu;
int main(){fnu=3;system (app2);}
where app2 is the secondary application:
#include "stdafx.h"
...
#include "iostream"
#include "avis_h.h"
int fnu;
int main(){cout<<fnu;Sleep(10);}
instead of the number 3 the number 0 is displayed. I've tried alternative ways but none worked so far. Can somebody please tell me how I get that value passed correctly from the main program to the secondary program?

You can't share variables between independent applications like that.
You can pass it as a parameter to the system command:
//commandLine is app2 + " " + the parameter
system (commandLine);
Breakdown:
std::stringstream ss;
ss << app2;
ss << " ";
ss << fnu;
std::string commandLine = ss.str();
system(commandLine.c_str());
and don't forget to:
#include <sstream>
#include <string>
and retrieve it via argv in the second application.
Or you can use IPC, but that's overkill in this particular case.

Applications have different address spaces and if you wish to pass some data from one application to another you can either write to a file in one application and read the file in another or you can use one of the inter process communication mechanisms supported by the underlying operating system. On Unix-like systems, these mechanisms are pipe, fifo, message queue and shared memory. You can even use sockets. To use the system function is somewhat not very nice. However, if you wish to use system function only, which is workable for this simple inter-process communication, try to pass the value of fnu as a parameter to app2.
char buf [20];
sprintf (buf, "app2 %d", fnu);
system (buf);

Related

Create and Modify System Path Variable

I am creating a C++ Application using Boost Library, so for I have developed modules but stuck here.
I want to Create and modify System Variables(Or Local Environment Variables that persist even after process has terminated) using boost library.
There are methods like
setenv()
putenv()
getenv()
but they make local changes and the value gets disappeared after the process has terminated.
Well that's not the real issue. The real problem arises when i want the same code to run on linux and mac platform.
Can I make a cross platform code using C++ with Libraries that can create and modify and delete the path variables ?
If not
Can I make a code for specific platform say Windows with the above requirements.
As of now I have this code that sets Environment Variable for windows but it give error
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <process/boost/process.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
namespace bp = boost::process;
namespace bpi = boost::process::initializers;
namespace bio = boost::iostreams;
int main()
{
char* str="SETX Name Value";
bp::pipe p = bp::create_pipe();
{
bio::file_descriptor_sink sink(p.sink, bio::close_handle);
boost::filesystem::path p("C:/Windows/System32/cmd.exe");
boost::system::error_code ec;
bp::windows::execute(bpi::run_exe(p),
bpi::set_cmd_line(str),
bpi::bind_stdout(sink),
bpi::set_on_error(ec)
);
}
bio::file_descriptor_source source(p.source, bio::close_handle);
bio::stream<bio::file_descriptor_source> is(source);
std::string s;
is >> s;
std::cout << s << std::endl;
std::cin.get();
return 0;
}
This has nothing to with Boost, and actually very little with environment variables.
It has to do with System configuration instead.
So, given you have the required permissions to alter the user/system environment you can use these methods to make the changes stick:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx
Most of the samples around favour tools like Windows Scripting Host, PowerShell and .NET to do the job:
Programmatically modifiy environment variables?
But you can probably translate it to C++ if you must.
PS. On Linux, you'd alter some files like /etc/profile, /etc/default/... etc.

Storing result in a file in C++

I'm writing a program to ping an IP.
I must ping a specific address for 1000s.
Now I want save the TTL to a file to draw it's histogram.
How I can do it? How can I just save the TTL to file?
Here's what I've tried:
#include "stdafx.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "conio.h"
#include <string>
#include <windows.h>
#include <iostream>
#include <fstream>
using namespace std;
static string host;
static string ping_again;
void ping()
{
cout << "Host: ";
host="www.yahoo.com";
system (("ping " + host).c_str);
}
int main()
{
ping();
return(0);
}
You've chosen to run the ping executable directly with system() and what you are missing is the capture of the output of the command, so you can parse the TTL.
Capturing stdout could have been done with popen instead of system, however, from your list of includes you seem to be on Windows, and that’s where it gets complicated. Check out this question: What is the equivalent to Posix popen() in the Win32 API?, and note that you can call popen if you application is a console application, otherwise the answers will refer you to an MSDN example which painfully details how you should invoke a process and redirect its input/output.
Once you redirect and capture the output you should parse the strings to extract the TTL. Note that the output of ping.exe may be different for different versions of Windows, and that you have little control what ping.exe you are actually invoking.
The alternative and the better approach is to use the ICMP APIs directly instead of invoking a ping executable on hosts where your application runs. Start with IcmpSendEcho and note that it provides the RTT in the reply structure.

How to redirect printf output back into code?

i'm writing a little c++ app to wrap around the opencv haar training function (namely cvCreateTreeCascadeClassifier). The function throws a whole load of output to the console and I wish to parse this output so that I can populate various variables in my code.
The function I wish to use is not part of the actual openCV library; instead it has to be built with my code as part of the project. All of the output from the the function is via printf.
Question: Is it possible to intercept the printf statements before they end up on the console? I've managed to redirect them using freopen but this seems a little clumsy as I then need to parse the file and then delete it when the function call is finished. Also, the function is likely to be running for several hours (and possibly even weeks!) so the size of the file might be an issue if its constantly being appended too.
Requirements: I need this app to be c++ and to run on both windows and linux (but have no problem with conditional compile statements if need be). I would also like to be able to still see my cout and cerr messages on the console (just not the printf).
My googling has removed my will to live! Can anyone help with a solution via either code example or pointers to places I should be looking for an answer?
Thanks
What you can do is:
create a pipe
make the writable end of the pipe the new stdout
read from the readable part of the pipe
Reading and writing should happen in different threads or you risk that your program starves on one end of the pipe.
Here's a sample how to do the redirection in unix & windows:
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)
#define fileno _fileno
#define dup2 _dup2
#define read _read
#endif
#include <assert.h>
int main()
{
int fds[2];
int res;
char buf[256];
int so;
res=pipe(fds);
assert(res==0);
so=fileno(stdout);
// close stdout handle and make the writable part of fds the new stdout.
res=dup2(fds[1],so);
assert(res!=-1);
printf("Hi there\n");
fflush(stdout);
// reading should happen in a different thread
res=read(fds[0],buf,sizeof(buf)-1);
assert(res>=0 && res<sizeof(buf));
buf[res]=0;
fprintf(stderr,"buf=>%s\n",buf);
return 0;
}
This code should print
buf=>Hi there
(I'm using assert here, because I am too lazy to do real error checking for this example)
Encapsulate the lib into an application, and pipe the application's output to your application. Now write a script so that you don't have to run the apps together every time with a pipe.
Take a look at: http://www.unix.com/programming/136225-reading-stdout-pipe.html it seems promising, but i never tried it.

Passing information between two seperate programs

I want to pass a value of an input variable in my program lets say#1 to another program #2 and i want #2 to print the data it got to screen, both are needed to be written in c++. The this will be on Linux.
Depending on the platform there are a number of options available. What you are trying to do is typically called inter-process communication (IPC).
Some options include:
Sockets
Pipes
Queues
Shared Memory
What is easiest is probably dependent on the platform youa are using.
As always, there is a Boost library for that (God, I like Boost).
Nic has covered all the 4 that I wanted to mention (on the same machine):
Sockets
Pipes
Queues
Shared Memory
If writing system calls is troublesome for you, you may want to use the following libraries:
Boost http://www.boost.org/
Poco http://pocoproject.org/blog/
Nokia Qt http://qt.nokia.com/
Something you can read from Qt portable IPC: only QSharedMemory?
If effeciency is not prime concern then use normal file i/o.
else go for IPC to do so.
As far as Windows is concern you have following options :
Clipboard ,
COM ,
Data Copy ,
DDE ,
File Mapping ,
Mailslots ,
Pipes ,
RPC ,
Windows Sockets
For Linux , use can use Name Pipes(efficient) or sockets.
If you're on Windows, you can use Microsoft Message Queueing. This is an example of queue mentioned previously.
If the data to be passed is just a variable, then one of the option is to set it as Environment Variable [ Var1 ] by program #1 and access it, in Program #2 [ if both are running on same env/machine ]. Guess this will be the easiest one, instead of making it complex, by using IPC/socket etc.
I think most of the answers have address the common IPC mechanisms. I'd just like to add that I would probably go for sockets because it's fairly most standard across several platforms. I decided to go for that when I needed to implement IPC that worked both on Symbian Series 60 and Windows Mobile.
The paradigm is straightforward and apart from a few platform glitches, the model worked the same for both platforms. I would also suggest using Protocol Buffers to format the data you send through. Google uses this a lot in its infrastructure. http://code.google.com/p/protobuf/
DBUS
QtDbus
DBus-mm
In response to your comment to Roopesh Majeti's answer, here's a very simple example using environment variables:
First program:
// p1.cpp - set the variable
#include <cstdlib>
using namespace std;;
int main() {
_putenv( "MYVAR=foobar" );
system( "p2.exe" );
}
Second program:
// p2.cpp - read the variable
#include <cstdlib>
#include <iostream>
using namespace std;;
int main() {
char * p = getenv( "MYVAR" );
if ( p == 0 ) {
cout << "Not set" << endl;
}
else {
cout << "Value: " << p << endl;
}
}
Note:
there is no standard way of setting an environment variable
you will need to construct the name=value string from the variable contents
For a very dirt and completely nonprofessional solution you can do it like me.
Save the variable in to a file and then read it (in an infinite loop every x time) with the other program.
fsexample.open("F:/etc etc ...");
fsexample >> data1 >> data2; // etc etc
and on the other side
fsexample.open("F:/etc etc ...");
fsexample << data1 << data2; // etc etc
The trick is that F is a virtual drive created with ramdisk so it is fast
and heavy-duty proof.
You could have problem of simultaneous access but you can check it with
if (!fsexample.is_open()) {
fsexample_error = 1;
}
and retry on failure.

How do I get the directory that a program is running from?

Is there a platform-agnostic and filesystem-agnostic method to obtain the full path of the directory from where a program is running using C/C++? Not to be confused with the current working directory. (Please don't suggest libraries unless they're standard ones like clib or STL.)
(If there's no platform/filesystem-agnostic method, suggestions that work in Windows and Linux for specific filesystems are welcome too.)
Here's code to get the full path to the executing app:
Variable declarations:
char pBuf[256];
size_t len = sizeof(pBuf);
Windows:
int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;
Linux:
int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;
If you fetch the current directory when your program first starts, then you effectively have the directory your program was started from. Store the value in a variable and refer to it later in your program. This is distinct from the directory that holds the current executable program file. It isn't necessarily the same directory; if someone runs the program from a command prompt, then the program is being run from the command prompt's current working directory even though the program file lives elsewhere.
getcwd is a POSIX function and supported out of the box by all POSIX compliant platforms. You would not have to do anything special (apart from incliding the right headers unistd.h on Unix and direct.h on windows).
Since you are creating a C program it will link with the default c run time library which is linked to by ALL processes in the system (specially crafted exceptions avoided) and it will include this function by default. The CRT is never considered an external library because that provides the basic standard compliant interface to the OS.
On windows getcwd function has been deprecated in favour of _getcwd. I think you could use it in this fashion.
#include <stdio.h> /* defines FILENAME_MAX */
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
return errno;
}
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */
printf ("The current working directory is %s", cCurrentPath);
This is from the cplusplus forum
On windows:
#include <string>
#include <windows.h>
std::string getexepath()
{
char result[ MAX_PATH ];
return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}
On Linux:
#include <string>
#include <limits.h>
#include <unistd.h>
std::string getexepath()
{
char result[ PATH_MAX ];
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
return std::string( result, (count > 0) ? count : 0 );
}
On HP-UX:
#include <string>
#include <limits.h>
#define _PSTAT64
#include <sys/pstat.h>
#include <sys/types.h>
#include <unistd.h>
std::string getexepath()
{
char result[ PATH_MAX ];
struct pst_status ps;
if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
return std::string();
if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
return std::string();
return std::string( result );
}
If you want a standard way without libraries: No. The whole concept of a directory is not included in the standard.
If you agree that some (portable) dependency on a near-standard lib is okay: Use Boost's filesystem library and ask for the initial_path().
IMHO that's as close as you can get, with good karma (Boost is a well-established high quality set of libraries)
I know it is very late at the day to throw an answer at this one but I found that none of the answers were as useful to me as my own solution. A very simple way to get the path from your CWD to your bin folder is like this:
int main(int argc, char* argv[])
{
std::string argv_str(argv[0]);
std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}
You can now just use this as a base for your relative path. So for example I have this directory structure:
main
----> test
----> src
----> bin
and I want to compile my source code to bin and write a log to test I can just add this line to my code.
std::string pathToWrite = base + "/../test/test.log";
I have tried this approach on Linux using full path, alias etc. and it works just fine.
NOTE:
If you are on windows you should use a '\' as the file separator not '/'. You will have to escape this too for example:
std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));
I think this should work but haven't tested, so comment would be appreciated if it works or a fix if not.
Filesystem TS is now a standard ( and supported by gcc 5.3+ and clang 3.9+ ), so you can use current_path() function from it:
std::string path = std::experimental::filesystem::current_path();
In gcc (5.3+) to include Filesystem you need to use:
#include <experimental/filesystem>
and link your code with -lstdc++fs flag.
If you want to use Filesystem with Microsoft Visual Studio, then read this.
No, there's no standard way. I believe that the C/C++ standards don't even consider the existence of directories (or other file system organizations).
On Windows the GetModuleFileName() will return the full path to the executable file of the current process when the hModule parameter is set to NULL. I can't help with Linux.
Also you should clarify whether you want the current directory or the directory that the program image/executable resides. As it stands your question is a little ambiguous on this point.
On Windows the simplest way is to use the _get_pgmptr function in stdlib.h to get a pointer to a string which represents the absolute path to the executable, including the executables name.
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
Maybe concatenate the current working directory with argv[0]? I'm not sure if that would work in Windows but it works in linux.
For example:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv) {
char the_path[256];
getcwd(the_path, 255);
strcat(the_path, "/");
strcat(the_path, argv[0]);
printf("%s\n", the_path);
return 0;
}
When run, it outputs:
jeremy#jeremy-desktop:~/Desktop$ ./test
/home/jeremy/Desktop/./test
For Win32 GetCurrentDirectory should do the trick.
You can not use argv[0] for that purpose, usually it does contain full path to the executable, but not nessesarily - process could be created with arbitrary value in the field.
Also mind you, the current directory and the directory with the executable are two different things, so getcwd() won't help you either.
On Windows use GetModuleFileName(), on Linux read /dev/proc/procID/.. files.
Just my two cents, but doesn't the following code portably work in C++17?
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char* argv[])
{
std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
}
Seems to work for me on Linux at least.
Based on the previous idea, I now have:
std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");
With implementation:
fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
{
static auto exe_parent_path = fs::path(exe_path).parent_path();
return exe_parent_path / filename;
}
And initialization trick in main():
(void) prepend_exe_path("", argv[0]);
Thanks #Sam Redway for the argv[0] idea. And of course, I understand that C++17 was not around for many years when the OP asked the question.
Just to belatedly pile on here,...
there is no standard solution, because the languages are agnostic of underlying file systems, so as others have said, the concept of a directory based file system is outside the scope of the c / c++ languages.
on top of that, you want not the current working directory, but the directory the program is running in, which must take into account how the program got to where it is - ie was it spawned as a new process via a fork, etc. To get the directory a program is running in, as the solutions have demonstrated, requires that you get that information from the process control structures of the operating system in question, which is the only authority on this question. Thus, by definition, its an OS specific solution.
#include <windows.h>
using namespace std;
// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
char currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
return string(currentDir);
}
For Windows system at console you can use system(dir) command. And console gives you information about directory and etc. Read about the dir command at cmd. But for Unix-like systems, I don't know... If this command is run, read bash command. ls does not display directory...
Example:
int main()
{
system("dir");
system("pause"); //this wait for Enter-key-press;
return 0;
}
Works with starting from C++11, using experimental filesystem, and C++14-C++17 as well using official filesystem.
application.h:
#pragma once
//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std {
namespace filesystem = experimental::filesystem;
}
#endif
std::filesystem::path getexepath();
application.cpp:
#include "application.h"
#ifdef _WIN32
#include <windows.h> //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h> //readlink
#endif
std::filesystem::path getexepath()
{
#ifdef _WIN32
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, path, MAX_PATH);
return path;
#else
char result[PATH_MAX];
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
return std::string(result, (count > 0) ? count : 0);
#endif
}
For relative paths, here's what I did. I am aware of the age of this question, I simply want to contribute a simpler answer that works in the majority of cases:
Say you have a path like this:
"path/to/file/folder"
For some reason, Linux-built executables made in eclipse work fine with this. However, windows gets very confused if given a path like this to work with!
As stated above there are several ways to get the current path to the executable, but the easiest way I find works a charm in the majority of cases is appending this to the FRONT of your path:
"./path/to/file/folder"
Just adding "./" should get you sorted! :) Then you can start loading from whatever directory you wish, so long as it is with the executable itself.
EDIT: This won't work if you try to launch the executable from code::blocks if that's the development environment being used, as for some reason, code::blocks doesn't load stuff right... :D
EDIT2: Some new things I have found is that if you specify a static path like this one in your code (Assuming Example.data is something you need to load):
"resources/Example.data"
If you then launch your app from the actual directory (or in Windows, you make a shortcut, and set the working dir to your app dir) then it will work like that.
Keep this in mind when debugging issues related to missing resource/file paths. (Especially in IDEs that set the wrong working dir when launching a build exe from the IDE)
A library solution (although I know this was not asked for).
If you happen to use Qt:
QCoreApplication::applicationDirPath()
Path to the current .exe
#include <Windows.h>
std::wstring getexepathW()
{
wchar_t result[MAX_PATH];
return std::wstring(result, GetModuleFileNameW(NULL, result, MAX_PATH));
}
std::wcout << getexepathW() << std::endl;
// -------- OR --------
std::string getexepathA()
{
char result[MAX_PATH];
return std::string(result, GetModuleFileNameA(NULL, result, MAX_PATH));
}
std::cout << getexepathA() << std::endl;
This question was asked 15 years ago, so the existing answers are now incorrect. If you're using C++17 or greater, the solution is very straightforward today:
#include <filesystem>
std::cout << std::filesystem::current_path();
See cppreference.com for more information.
On POSIX platforms, you can use getcwd().
On Windows, you may use _getcwd(), as use of getcwd() has been deprecated.
For standard libraries, if Boost were standard enough for you, I would have suggested Boost::filesystem, but they seem to have removed path normalization from the proposal. You may have to wait until TR2 becomes readily available for a fully standard solution.
Boost Filesystem's initial_path() behaves like POSIX's getcwd(), and neither does what you want by itself, but appending argv[0] to either of them should do it.
You may note that the result is not always pretty--you may get things like /foo/bar/../../baz/a.out or /foo/bar//baz/a.out, but I believe that it always results in a valid path which names the executable (note that consecutive slashes in a path are collapsed to one).
I previously wrote a solution using envp (the third argument to main() which worked on Linux but didn't seem workable on Windows, so I'm essentially recommending the same solution as someone else did previously, but with the additional explanation of why it is actually correct even if the results are not pretty.
As Minok mentioned, there is no such functionality specified ini C standard or C++ standard. This is considered to be purely OS-specific feature and it is specified in POSIX standard, for example.
Thorsten79 has given good suggestion, it is Boost.Filesystem library. However, it may be inconvenient in case you don't want to have any link-time dependencies in binary form for your program.
A good alternative I would recommend is collection of 100% headers-only STLSoft C++ Libraries Matthew Wilson (author of must-read books about C++). There is portable facade PlatformSTL gives access to system-specific API: WinSTL for Windows and UnixSTL on Unix, so it is portable solution. All the system-specific elements are specified with use of traits and policies, so it is extensible framework. There is filesystem library provided, of course.
The linux bash command
which progname will report a path to program.
Even if one could issue the which command from within your program and direct the output to a tmp file and the program
subsequently reads that tmp file, it will not tell you if that program is the one executing. It only tells you where a program having that name is located.
What is required is to obtain your process id number, and to parse out the path to the name
In my program I want to know if the program was
executed from the user's bin directory or from another in the path
or from /usr/bin. /usr/bin would contain the supported version.
My feeling is that in Linux there is the one solution that is portable.
Use realpath() in stdlib.h like this:
char *working_dir_path = realpath(".", NULL);
The following worked well for me on macOS 10.15.7
brew install boost
main.cpp
#include <iostream>
#include <boost/filesystem.hpp>
int main(int argc, char* argv[]){
boost::filesystem::path p{argv[0]};
p = absolute(p).parent_path();
std::cout << p << std::endl;
return 0;
}
Compiling
g++ -Wall -std=c++11 -l boost_filesystem main.cpp