I know there are many similar topics but there are equally many unique mistakes that may lead to this problem (so I think). Therefore I ask, after some research.
My problem is that the compiler, GNU GCC, when compiling one file does not see my namespace declared in another file. The IDE (CodeBlocks) evidently does see it as it auto-completes the name of the namespace. I tried to isolate the problem and came up with this:
File main.cpp:
namespace MyName
{
int MyVar;
}
#include "T1.cpp"
int main()
{
return 0;
}
File T1.cpp:
using namespace MyName;
error: 'MyName' is not a name-space name.
In my project I have a header file, say T1.h, and an implementation file T1.cpp — and MyName isn't accessible in either of them.
Any help or guidance would be appreciated.
What's happening is that CodeBlocks is compiling both main.cpp and T1.cpp. Here is what happens when you try to compile each one:
main.cpp:
$ g++ main.cpp
$
T1.cpp
$ g++ T1.cpp
T1.cpp:1:17: error: ‘MyName’ is not a namespace-name
using namespace MyName;
^
T1.cpp:1:23: error: expected namespace-name before ‘;’ token
using namespace MyName;
^
$
T1.cpp, when compiled on it's own, has no knowledge of MyName. To fix this, don't include .cpp files, and put your declarations in header files.
Edit: From what I gather, this may be a better way to organize your example:
T1.h:
namespace MyName {
extern int MyVar;
}
T1.cpp
#include "T1.h"
int MyName::MyVar = 5;
main.cpp
#include "T1.h"
#include <iostream>
using namespace MyName;
int main()
{
std::cout << MyVar << std::endl;
return 0;
}
Now it will compile correctly:
$ g++ -c T1.cpp -o T1.o
$ g++ -c main.cpp -o main.o
$ g++ T1.o main.o
$ ./a.out
5
Related
I want to write a shared library and I want to get a compiler/linker error if I forgot to implement some functions.
Consider the following case:
test.h
class Test {
public:
Test();
};
test.cpp
#include "test.h"
main.cpp
#include "test.h"
int main() {
new Test();
}
If I create a library with this command gcc -c -fpic test.cpp && g++ -shared -o libtest.so -Wl,--no-undefined -Wl,--no-allow-shlib-undefined test.o there is no error message, but the library is broken. Is there a way to force the creation of a not broken library?
Edit: adding additional flag, but doesn't change result
These codes have been modified:
test.h :
class Test {
public:
Test();
};
test.cpp :
#include "test.h"
Test::Test(){} // you must implement the constructor
You must have to implement the constructor, and if not, you get an error "undefined reference to `Test::Test()'".
main.cpp :
#include <iostream>
#include "test.h"
using namespace std;
int main(void)
{
Test* t = new Test(); // you must define a pointer
cout << "test* was created: " << t << endl;
delete t;
t = nullptr;
return 0;
}
Now all the code is OK. Then we create a shared-library with the following command:
g++ -shared -o test.so -fPIC test.cpp
Finally, we compile the main.cpp file at the same time as referring to the test.so shared-library and get the exe output, by the command below:
g++ -g main.cpp test.so -o test.exe
I am trying to link a dll with a very simple testing program, but I am getting an error, that I will describe at the end of the post.
frvt11.h - Interface (just relevant code) I need to implement to create my dll
namespace FRVT {
class Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.h - Header of my implementation of Inteface
#include "frvt11.h"
namespace FRVT {
class Implementation : public FRVT::Interface {
public:
static std::shared_ptr<Interface>
getImplementation();
}
}
implementation.cpp - My implementation of Interface
UPDATE: change from Implementation::getImplementation to Interface::getImplementation
#include "implementation.h"
using namespace FRVT;
std::shared_ptr<Interface>
Interface::getImplementation() {
std::cout<<"getImplementation";
return std::make_shared<Implementation>();
}
main.cpp
UPDATE: Explicitly indicate the namespace Interface::
#include "frvt11.h"
using namespace FRVT;
int main(){
auto obj = Interface::getImplementation();
return 0;
}
compilation directives
UPDATE: include of -L/dll-directory where are all .h, .cpp and dll
g++ -std=c++11 -c -Wall -Werror -m64 -fPIC implementation.cpp
g++ -std=c++11 -shared -m64 -o libimplementation.so implementation.cpp
g++ -std=c++11 -Wall -m64 -o main main.cpp -L/dll-directory -limplementation
error
UPDATE: Original problem solved
main.cpp: In function 'int main()':
main.cpp:6:34: error: 'getImplementation' was not declared in this scope
auto obj = getImplementation();
How to solve this error? I was expecting that the linker would do the "magic" to say to main.cpp, that the implementation of referred function would be at the dll. What am I doing wrong?
At implementation.cpp I've changed from:
Implementation::getImplementation()
to:
Interface::getImplementation()
At main.cpp I've explicitly indicate the interface, like bellow:
auto obj = Interface::getImplementation();
And finally I've used the -L directive to indicate where was the the generated dll.
UPDATE:
Removed old question about .so files. They aren't intended to work on Windows.
I solved the below using a header file. I am guessing it is a standard convention to use .h file every time you link using C++?
mydll.h:
#ifndef mydll_h_
#define mydll_h_
void hello();
#endif
myprog.cc:
#include "mydll.h"
int main ()
{
hello ();
return 0;
}
mydll.cc:
#include <iostream>
void hello()
{
std::cout << "Hello World!\n";
}
Alternatively, I tried .dll library using Cygwin with this guide: https://cygwin.com/cygwin-ug-net/dll.html
The compilation for their .c files work, but I am trying to get it to work for my .cc files. Any ideas?
mydll.cc:
#include <iostream>
void hello()
{
std::cout << "Hello World!\n";
}
myprog.cc:
int main ()
{
hello ();
return 0;
}
I typed:
g++ -c mydll.cc
g++ -shared -o mydll.dll mydll.o
But when I type:
g++ -o myprog myprog.cc -L./ -lmydll
I get:
myprog.cc: In function ‘int main()’:
myprog.cc:4:10: error: ‘hello’ was not declared in this scope
hello ();
You're facing a compiler problem; not a linker problem. The compiler is telling you that when it compiles myprog.cc, it can't find function hello().
You need to write a function declaration for hello(). Note: you're function definition for hello() is in mydll.cc.
A function declaration would simply be:
void hello();
(1) You could place this one line of code in your myprog.cc above int main().
(2) You could also place this one line of code in a header file that is included at least by myprog.cc and optionally by mydll.cc. But good programming practice dictates that the header file should be included by both.
If you follow option 1, the following version of myprog.cc will fix your compiler error:
void hello(); // "extern void hello();" would be more proper.
int main ()
{
hello ();
return 0;
}
Option 2 would entail:
myprog.cc:
#include <mydll.h>
int main ()
{
hello ();
return 0;
}
Either way results in successful compilation and execution:
>g++ -c mydll.cc
>g++ -shared -o mydll.dll mydll.o
>g++ -o myprog myprog.cc -L./ -lmydll
>./myprog.exe
Hello World!
>
This question already has answers here:
creating classes link error
(2 answers)
Closed 8 years ago.
I'm trying to learn how to make classes in C++ where I use a header file, a .cpp file that contains the class function definitions, and a main .cpp file. Here is what I have (taken from an example)
in class.h
class MyClass
{
public:
void foo();
int bar;
};
in class.cpp
#include "class.h"
using namespace std;
void MyClass::foo()
{
cout<< "test";
}
in main.cpp
#include "class.h"
using namespace std;
int main()
{
MyClass a;
a.foo();
return 0;
}
Compiling the main.cpp results in this error:
[Linker error] C:\:(.text+0x16): undefined reference to `MyClass::foo()'
collect2: ld returned 1 exit status
Do I need to compile the class.cpp or class.h? Am I missing a way of linking class.h with class.cpp? If so how do I link them?
You need to compile the implementation files into object files and link them together. The following is an example for when you are using g++:
g++ -c class.cpp -o class.o
g++ -c main.cpp -o main.o
g++ class.o main.o -o main
./main
In reality, you would add more options like -std=c++11 -O3 -Wall -Wextra -Werror etc.
You can try this on Linux shell using g++
Compile Create object files of main.cpp and class.cpp called main.o and class.o
g++ -c class.cpp
g++ -c main.cpp
Linking the object codes main.o and class.o to create executable file called program
g++ -o program main.o class.o
then run the program executable file
./program
You are likely to be compiling only main.cpp and not class.cpp.
What command are you using to generate the output ?
This should work fine :
g++ class.cpp main.cpp -o class
Its working fine
I tried the code in my Compiler
MyClass.h
#include <iostream>
class MyClass
{
public:
void foo();
int bar;
};
MyClass.cpp
#include "MyClass.h"
using namespace std;
void MyClass::foo()
{
cout<< "test";
}
Main.cpp
#include <iostream>
#include "MyClass.h"
int main(int argc, const char * argv[])
{
MyClass a;
a.foo();
return 0;
}
Ive tried the code in Xcode.
Its working just fine.
Use compiler option -I<dir of .h file> while compiling .cpp file. Compile both the .cpp files
My code is:
test.cpp
#include<iostream>
#include<boost/bind.hpp>
#include "extern.h"
using namespace std;
using namespace boost;
int fun(int x,int y){return x+y;}
/*
*void add(int &m,int &n);
*/
int main(){
int m=1;int n=2;
cout << m << " "<< n << endl;
add(m,n);
cout << m << " "<< n << endl;
return 0;
}
extern.h:
#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;
void add(int &n,int &m);
extern.cpp:
#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;
extern int m;
extern int n;
void add(int &n,int &m) {
n = n+1;
m = m+1;
}
When I compile it with
g++ -Wall -o test test.cpp
It turns out to be:
/tmp/ccMHVRNo.o: In function `main':
test.cpp:(.text+0x7b): undefined reference to `add(int&, int&)'
collect2: ld returned 1 exit status
But when I compile it with:
g++ -Wall -o test test.cpp extern.cpp
It works well:
$ ./test
1 2
2 3
So the reason is that test.cpp can't find the implementation of the add() function.
But I have added extern.h to test.cpp, why does it still say "undefined reference to add(int&, int&)"?
The header file extern.h only tells your program how the prototype of the function is made. The linker needs the actual implementation of the function, so it looks for the code add(int&,int&) references to, and it cannot find it unless you give to the compiler all the files it needs (in this case, extern.cpp is the file the linker needs when looking for the add function).
The implementation of the function void add(int&,int&) is in the source file extern.cpp. The compiler can't know that this files is related to the program until you tell it.
You must specify all source files at the command line:
g++ -Wall -o test test.cpp extern.cpp
If you want to avoid compiling of all source files you can also specify the already compiled object file:
g++ -Wall -o test test.cpp extern.o
When you don't want to think every time what commands you need to compile you should use make and create an Makefile with rules that define how the target is build. with the makefile you can just start
make
and get the result.
This is the usual formula:
g++ -Wall -c test.cpp
g++ -Wall -c extern.cpp
g++ -o test test.o extern.o
There are one-liners, but those don't scale so well to larger projects.