I am learning (trying) how to write my own C/C++ headers, and get functions out of the body of my code. For this I wrote nyanlib.h, and nyan.cpp
Ignoring that its a trivial program, please tell me if the header is written correctly, or if I am making serious mistakes? The code works though.
Here is nyan.cpp:
#include <iostream>
#include <unistd.h>
#include "nyanlib.h"
using namespace std;
int main()
{
while( true )
{
print_nyan(); //function from nyanlib
sleep(1);
}
return 0;
}
and Here is nyanlib.h
Also, Would nyanlib.h be a shared library or a static library?
What you have as nyanlib.h should be renamed to nyanlib.cpp. Then nyanlib.h would contain only the following:
#ifndef NYANLIB_H
#define NYANLIB_H
void print_nyan();
#endif
You can then compile the library as an object file:
g++ -c nyanlib.cpp
This gives you nyanlib.o. So now your main file contains just a prototype of print_nyan() from the header file so it knows how to call it.
Then you compile the main program:
g++ -c nyan.cpp
g++ -o nyan nyan.o nyanlib.o
Yes and no. While it is a valid header, you are using it a bit strangely. Most of the time, a header is used as a way to expose methods and variables related to the class and not to perform functionality.
For your case if you want to make it "better", I would bring the implementation of the print_nyan() function into the cpp file, and just leave a prototype of the function in the header.
And I would say that it is neither a static nor a shared library since it has a main. If you wanted to make it a library, you should make a separate header and source file that defines the print_nyan() function, make that your library, and use that library in your main function.
Related
I have this simple code in C++
#include <something.h>
#include <something2.h>
int main()
{
my_function();
return 0;
}
function with name my_function is defined in something.h and also in something2.h How to choose whichone I want to use without editting included files?
One solution is to use
namespace something_one
{
#include <something.h>
}
namespace something_two
{
#include <something2.h>
}
This works well if all the code is in the headers.
Otherwise you have to resort to #defines, stub functions implemented in carefully crafted compilation units, or a robust conversation with the global namespace polluter.
Assuming that actual definition resides in something.cpp (or .c) and something2.cpp (or .c),
Link only one of something.o or something2.o at the time of creating main application executable, depending upon from which file you want function to get executed.
With linking the correct file, you do not need to change any source code.
you might have to declare them as extern "C" at the point declaration and definition if you are compiling it as c++ files with g++ or gcc -std=c++0x or gcc -std=c++11.
I'm trying to deal with this problem for some time and I can't seem to find the solution. I'm getting error:
one or more multiply defined symbols found
I faced this error while dealing with something more complicated, but even simple examples like this one don't work for me. Here is my main.cpp:
#include "defs.cpp"
int main()
{
string a = "A";
printIt(a);
}
, and here is my defs.cpp:
#include "header.h"
void printIt(string a)
{
cout << a;
}
, and this is my header.h:
#include <string>
#include <iostream>
using namespace std;
void printIt(string a);
I guess this is something trivial, but please don't rage if you think this is duplicate, because I'm a beginner and I didn't understand more complicated examples. Some help would be appreciated.
When you see #include "defs.cpp" you need to get very suspicious: cpp files are not meant to be included; only header files are designed for that.
Instead of including a cpp file, write a header for it. It appears that you have a suitable header already - your header.h, which contains the forward declaration of printIt:
void printIt(string a);
Now replace #include defs.cpp with #include "header.h", and compile your code. This should fix the problem.
Compiling this depends on the system where you are trying it out. On UNIX-like systems, you would write
g++ defs.cpp main.cpp
./a.out
You should not #include a CPP file. Only include header files containing the function prototype definitions. If no such header file exists, put the function prototype in your program (for eg. in file where main is written).
In your case, you are including (directly/indirectly) the CPP file which is having the definition of the function. Since same definition is compiled through CPP files, compiler is putting them into .OBJ file (known as intermediate or object files). The linker finally attempts to combine these Object files, and says some function (symbol) is multiply defined.
In main.cpp you are including defs.cpp which includes a definition of printIt. So the translation unit corresponding to main.cpp defines printIt.
However, you are also compiling defs.cpp which defines printIt. defs.cpps corresponding translation unit thus defines printIt too.
Combining both into one program would lead to multiple (yet equivalent) definitions of this function which is forbidden by the ODR. Remove the #include directive and your program should link correctly.
This is because you are including:-
#include "defs.cpp"
and due to this there are multiple definitions of method printIt.
These are some basic rules:-
1) You must always include only header files in your source files. Even then you have to make sure header files are included only once because if it is included more than once then there could again be problem of multiple definition.To protect against that your header files should contain header gaurds.
2) C++ always adheres with single definition rule. However , you can have as many declaratons as possible as long as all declarations are consistent.
This is a really basic question, and I have found a lot of conceptual answers online, but failed to actually make it work.
Here is what I have:
file source.cc
#include <iostream>
int myfunc() {
return 42;
}
int main() {
return 0;
}
and then I create an object file source.o via:
g++ -c source.cc
finally, I use
ar rvs source.a source.o
to get the source.a static library.
Now, here comes trouble.
file user.cc looks like this:
#include <iostream>
#include <source.a>
int main() {
std::cout << myfunc();
}
where I evidently want to use the function defined in the library, but when trying to compile the user.cc:
g++ user.cc -o user
the error I get is:
user.cc:2:22: fatal error: source.a: No such file or directory
compilation terminated.
#include is compile time and must be C/C++ header (not library) containing e.g this
extern int myfunc();
than you have to use linker to compile it all togehter (specify all the files needed on the command line)
In addition to what others already wrote on the syntax to properly use g++ on the command line, you may want to consider the following notes on your code organization.
In your library code, you should not define the main() function. The definition of main() should instead be part of the code that uses your library, i.e the file user.cc in your example.
Moreover, you may want to distribute to the clients of the library a header file, that they can use to import the declarations of the functions exported by the library.
So, consider defining some files like this:
Header File:
// library.h -- Public header for your library's clients
#pragma once // or use #ifndef/#define/#endif "header guards"
// Functions exported by your library:
// their *declarations* go in the library's public header file;
// their *definitions* go in the library's implementation file(s) (.cc, .cpp)
// (exception: inline functions/methods, that are implemented in headers).
int myfunc();
// Add some other exported functions...
// NOTE: "extern" not needed in C++!
Implementation File:
// library.cc -- Library implementation code
#include "library.h" // library public header
#include <...> // headers required by this implementation code
// *Define* functions exported by the library
int myfunc() {
return 42;
}
// ...other function implementations...
Then, the library's client will just do:
File containing main() and using your library:
// main.cc (or user.cc or whatever you call it)
#include <iostream> // For std::cout, std::endl
...#include any other required header file...
#include "library.h" // Your library public header file
int main() {
// Call library's function
std::cout << myfunc() << std::endl;
}
// NOTE: main() is special: "return 0;" can be omitted.
Don't #include a library archive. It does not contain source code. It contains object code. Put it on the linker's command line.
Compile with g++ -c user.cc.
Link with g++ -o user user.o source.a.
In C++ (and C99), every function you call much be declared ahead of time. To do this you provide the "signature" of the function, without the the definition. In your case, this would be the statement
int myfunc();
which tells the compiler that myfunc is a function which takes no arguments and returns an int. Typically you would include this function declaration in a header.
A .a file is a compiled archive which does not contain C or C++ code, so #include-ing it into a C++ file will not work. Instead you need to create a C or C++ header, and add the .a archive to the list of files to be linked into the final executable. With g++, this is quite easy, you can say
g++ user.cc source.a -o executable
for example.
By default the #include <...> construct (with angle brackets) search system directories to find the specified files. To search other directories you can use the -L option, and to link with your library you need to use source.a in the command line. Like this:
g++ user.cc -L/path/to/library source.a -o user
A couple of ideas to add to the discussion
1) You should create a header file called source.h that contains the line
int myfunc();
or,
extern int myfunc();
2) In user.cc at the top should be a line
include "source.h"
This will tell the compiler the function is defined
3) I think you should take the main function out of source.cc, or at least make it static
As others have pointed out, you can't include a library file (source.a)
your compile and link process should work as is.
You can use headear files using #include. If you want to use libraries you have to tell the linker where to look for library files.
Check these articles for static and dynamic libraries:
Static and dynamic libraries
Using libraries in VS2005
Using libraries in Code::Blocks
I'm trying to compile some code that use a function implemented in a static library named staticlib.a. I also have the header named staticlib.h which contain the declaration of that function. My main, that is contained in the main.c file wich include staticlib.h, only calls that function and no else. So I compile with
gcc main.c staticlib.a
and everything work fine. I need some feature of c++ but if I properly change main.c in main.cpp and compile same way
gcc main.cpp staticlib.a
an undefined reference to my function occured. How can I make this works? And why this problem occurred? I cannot really find an explanation in any site i visited...
Thank you for all trhe answers.
you have to define the function in the library as a 'C' function, not a C++ function - do this in your main.cpp
extern "C"
{
#include "staticlib.h"
}
C and C++ compile differently, C++ uses name mangling (embedding C++ type information in the object file). To stop this behaviour so that you can link to C code from C++, you can use the extern C syntax in C++ when including the C header file.
Please see here
http://www.cplusplus.com/forum/general/1143/
Here's the situation:
I have three files, Test1.cpp and Test2.cpp. Test1.cpp can be compiled as-is into a stand-alone application. Test1.cpp also contains some functions that I would like to re-use in Test2.cpp. I'm using an #ifndef #endif block to conditionally exclude the main function of Test1.cpp so that when I compile Test2.cpp, the main function in Test2.cpp will be able to call functions defined in Test1.cpp. Example code:
--------------------------------------------
//File: Test1.h
#include <iostream>
void do_something();
--------------------------------------------
//File: Test1.cpp
#include "Test1.h"
void do_something();
{
std::cout<<"Done"<<std::endl;
}
#ifndef FN_MAIN
int main()
{
do_something();
return 0;
}
#endif
--------------------------------------
//File: Test2.cpp
#define FN_MAIN
#include "Test1.h"
int main()
{
do_something();
return 0;
}
--------------------------------------
Calling g++ with Test1.cpp works fine and behaves as expected, but calling g++ with Test2.cpp and Test1.cpp fails because main gets defined multiple times. However, calling g++ with -DFN_MAIN and the two source files fixes this problem. Is there any way to get around this? I'm thinking that this problem is coming from my less-than-complete understanding of the C++ preprocessor.
Note: My motivation for doing this is to reduce the size of the code on the project that I'm working on. The actual project includes both a stand-alone version of Test1.cpp and several other programs that use functions from Test1.cpp.
The preprocessor runs sequentially through each source file. Macros defined in one .cpp file do not affect macros defined in another .cpp file.
One option is to define FN_MAIN in the header: then when Test1.cpp includes that header the macro will still be defined. However, I think it's probably cleaner to define the macro on the command line; it depends on what your specific use case is though.
Another option would be to move the Test1.cpp main() into a separate .cpp file and build a separate executable with it.
To solve your problem this way you should use #include "Test1.cpp" in Test2.cpp instead of including Test1.h and then only call g++ with Test2.cpp. That way you'll be compiling just one compilation unit consisting of all the source from both Test1.cpp and Test2.cpp.
However - that's a pretty bad idea, so don't do that.
What you should do instead is organize your utility functions into individual files, say, initially just in one single file Common.cpp with header file Common.h to keep things really simple. Then you compile and link those files into each executable you're going to make. That's the right way to do it, it's much easier to understand and work with, and using several source-files doesn't make you apps any bigger.
In your case, having moved your common methods into say Common.cpp/h, you'll then do something like this:
g++ Test1.cpp Common.cpp # to build Test1.exe
g++ Test2.cpp Common.cpp # to build Test2.exe