How to execute compiled C++ code outside MinGW bin folder? - c++

Hi I'm compiling C++ code using MinGW G++ compiler. I've also added the PATH to the address C:\MinGW\bin; as an environment variable.
I can access G++ from command prompt and compile the code, but I can only execute the file if the .exe file is in the bin folder. (I'm guessing it requires the .dll files).
If the .cpp file is compiled outside of bin folder, it is giving me an error:
The procedure entry point __cxa_throw_bad_array_new_length could not be located in the dynamic link library C:\MinGW\testcode.exe
Is there any way I can compile and also execute the code directly from command prompt if it's in other folders?
This is a program that I worked with:
// Cpp program to illustrate the
// concept of Constructors
#include <iostream>
using namespace std;
class construct
{
public:
int a, b;
// Default Constructor
construct()
{
a = 100;
b = 200;
}
};
int main()
{
// Default constructor called automatically
// when the object is created
construct c;
cout << "a: "<< c.a << endl << "b: "<< c.b;
return 1;
}
If I compile basic code like "Hello World", it is running outside of the bin folder. But for a bit bigger code like the one above isn't executing.
The compilation command that I'm using is:
g++ testcode.cpp -o testcode

Related

Codelite linker undefined reference error

I'm new to codelite and c++. I'm using Linux and the g++ compiler. I've set up a simple project with two source files just to play around with linker errors. The files look like so:
Main.cpp:
#include <iostream>
void Log(const char*);
static int Multiply (int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
Log.cpp:
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
As you can see, Log.cpp simply specifies a function called in main. Both files are in the same directory, "src". So far all my settings are pretty much default, still I get an "undefined reference to `Log(..." error when I try to build this project.
Also, if I comment out the declaration of the Log function at the top of main.cpp, I would expect a compilation error since an undeclared function being called. Yet if I try to compile main.cpp I get no errors.
This is what my workspace looks like
Project settings
Compiler settings
Linker settings
Am I correct to expect the behaviors described above? Is there some setting I have to manually configure?

Pybind11 - Where to put PYBIND11_MODULE

Im currently playing around with pybind11 a bit. Im trying to create a C++ class which then gets passed to a python interpreter embedded in my C++ source.
I created some dummy class just to test the basic functionality I kept everything in a single source file. This approach compiled and ran without any problems.
Now I separated my dummy Class Test into a Test.h and Test.cpp
Test.h
#pragma once
#include<iostream>
#include"pybind11\pybind11.h"
namespace py = pybind11;
class Test
{
public:
Test(const std::string &s);
~Test();
void printStr();
private:
std::string _s;
};
Test.cpp
#include "Test.h"
PYBIND11_MODULE(TestModule, m)
{
py::class_<Test>(m, "Test")
.def(py::init<const std::string &>())
.def("printStr", &Test::printStr);
}
Test::Test(const std::string &s) : _s(s)
{
}
Test::~Test()
{
}
void Test::printStr()
{
std::cout << "---> " << _s << std::endl;
}
main.cpp
#include"Test.h"
int main(int argc, char **argv)
{
PyImport_AppendInittab("TestModule", PyInit_TestModule);
Py_Initialize();
PyRun_SimpleString("import TestModule");
PyRun_SimpleString("t = TestModule.Test(\"str\")");
PyRun_SimpleString("t.printStr()");
Py_Finalize();
getchar();
return 1;
}
After putting the Class Test into a new file the Compiler cannot find the PyInit_TestModule (main.cpp line: 6) anymore since this is generated by the PYBIND11_MODULE Macro which lives in the Test.cpp file(MSVS2017 Error: C2065).
I tried putting the PYBIND11_MODULE Macro into the Test.h. This however resulted in a linker error which said that "_PyInit_TestModule" is already defined in main.obj (MSVS2017 Error: LNK2005)
Putting the PYBIND11_MODULE Macro in the main.cpp file works.
However I feel like this will become quite unreadable as soon as you put a lot of custom Module definitions into main.cpp or even worse you have multiple Python-Interpreter being started from different source files where you then
need to put the same definition in all those files which will be a mess and most likely turn into a linker error.
Has one of you faced the same Problem and how did you solve it?
I created a file of his own for the bindings, and compiled/linked it together with the original c++ file. This way:
1) Test.h + Test.cpp contain only c++ code of your class
2) Test-bindings.cpp contains the PYBIND11_MODULE and #include <Test.h>
3) Building (with cmake). You will get a PyTest.so file out of it, that you can load in python.
# c++ libray
add_library(TestLib SHARED /path/to/Test.h /path/to/Test.cpp)
# bindings
add_subdirectory(pybind11) # you must have downloaded this repo
include_directories(/path-only/to/Test.h)
pybind11_add_module(PyTest SHARED /path/to/Test-bindings.cpp /path/to/Test.cpp)
4) (I suggest you to) write the main in python, using the python-binding you just created
5) In your main.py
import PyTest
# do something

Xcode does not share static variable with shared library

I've been working on a couple established C++ projects that use static variables from a shared library to store parameters. When compiled with g++ or clang++, the static variable is shared (has the same memory location) throughout the entire program. However, when compiled with Xcode, the main function static variable has a different memory location than the shared library static variable. Is there a way to get Xcode to compile/run the code the same as g++ or clang++, while still being able to debug with Xcode?
Please see example below:
main.cpp:
#include <iostream>
#include "Params.hpp"
int main(int argc, const char * argv[]) {
Params param = Params();
param.addParams();
std::vector<int> vi = Params::ParamsObj();
vi.push_back(10);
for(std::vector<int>::iterator it = vi.begin(); it != vi.end(); ++it) {
std::cout << "i = " << *it << std::endl;
}
return 0;
}
Params.hpp:
#ifndef Params_hpp
#define Params_hpp
#include <vector>
class Params{
typedef std::vector<int> ParamVector;
public:
static ParamVector& ParamsObj() {
static ParamVector m;
return m;
}
void addParams();
};
#endif /* Params_hpp */
Params.cpp:
#include "Params.hpp"
void Params::addParams(){
Params::ParamsObj().push_back(5);
}
Makefile:
clang:
clang++ -dynamiclib Params.cpp -o libshared_clang.dylib
clang++ main.cpp -o main_clang ./libshared_clang.dylib
gpp:
g++-mp-4.9 -Wall -shared -fPIC -o libshared_gpp.so Params.cpp
g++-mp-4.9 -Wall -o main_gpp main.cpp ./libshared_gpp.so
Output from both g++ and clang++ is:
i = 5
i = 10
While Xcode only outputs i = 10.
If I don't use a shared library and compile everything into one binary, Xcode will properly output both print statements.
My current solution is to add the project's main function into its own shared library and then create an Xcode specific file which merely calls the main function in the newly created shared library. However, I was hoping for a solution that didn't require changing the underlying project's code.
I'm pretty sure that if you turn on optimalization for gcc/clang (which you did not in your example), they will produce the same behavior as your compilation with XCode (which isn't a compiler, but an IDE).
Your problem is that the ParamsObj() function is inline (defining it in the class body adds an implicit inline keyword to it), allowing the compiler to just "paste" it into the main method instead of calling it.
With dll boundaries, this might result in the allocation of multiple static variables, if the function is used in multiple libraries (in your case, it's used in the dll, and inlined into the main executable).
Refactor the ParamsObj() method into a declaration and a separate definition in the corresponding C++ file, and you'll get the same behavior everywhere, printing both numbers.

systemc library can't be opened with vs 2013

I am new to systemc programming.For the installation, I followed this tutorial to install and startup. I am trying to build a simple main program. However I am getting the error
error LNK1104: cannot open file "systemc.lib".
Now with a simple directory search, I am not finding the file. However it seems that removing it causes more damages.
According to this poste The fact that the tutorial is for vs2010 and I am using vs2013 shouldn't be a problem.
How do I move foward. What should I do. Here is the code:
// Hello_world is module name
SC_MODULE(hello_world) {
SC_CTOR(hello_world) {
// Nothing in constructor
}
void say_hello() {
//Print "Hello World" to the console.
cout << "Hello World.\n";
}
};
// sc_main in top level function like in C++ main
int sc_main(int argc, char* argv[]) {
hello_world hello("HELLO");
// Print the hello world
hello.say_hello();
return(0);
}
From your second link, the reason why you don't have the library is simple: because you didn't build it. You should have the source files to build the library.

Do I need to build TinyThread++?

I've extracted the sources from the zip file at the website and put them in Code::Blocks' 'include' folder, but even then it cannot compile the provided 'hello.cpp' example.
(For reference:)
#include <iostream>
#include <tinythread.h>
using namespace std;
using namespace tthread;
// This is the child thread function
void HelloThread(void * aArg)
{
cout << "Hello world!" << endl;
}
// This is the main program (i.e. the main thread)
int main()
{
// Start the child thread
thread t(HelloThread, 0);
// Wait for the thread to finish
t.join();
}
And these are the following errors:
|41|undefined reference to `tthread::thread::thread(void (*)(void*), void*)'|
|44|undefined reference to `tthread::thread::join()'|
|44|undefined reference to `tthread::thread::~thread()'|
|44|undefined reference to `tthread::thread::~thread()'|
The same thing happens with wxDev-C++. Am I missing something; like, do I need to build the libraries or anything? If so, how?
From the readme.txt inside the archive:
Using TinyThread++
To use TinyThread++ in your own project, just add tinythread.cpp and
tinythread.h to your project. In your own code, do:
#include <tinythread.h>
using namespace tthread;
If you wish to use the fast_mutex class, inlude fast_mutex.h:
#include <fast_mutex.h>
Just including the header leads to unresolved symbols because the .cpp does not get compiled.
TinyThread is tiny.
In additional to including the headers, you just add the TinyThread.cpp to your project or ensure that it builds as part of your project.
The particular error happened to me in VC++ until I added the CPP file to my project.
The thread class and methods were not getting compiled otherwise.