Here a person asks "How to make your own library in C++ ?". This is exactly the question that I have. There is an answer to this question:
Create the files "mylibrary.h" and "mylibrary.cpp".
Only compile the library, and it shouldn't have a "main()" function in
it. This step will generate an object file called "myfile.o".
Create another file called something like "main.cpp". In main.cpp
you need to #include "mylibrary.h".
Compile main.cpp and add the library from step 2 to link in (in this case "myfile.o"). If you don't add this library, you'll get a
error message like "linker error - can't find function definition", or
something like that.
But I still have some questions:
The Library.cpp should have a main() function. But what should be in this main function? I do not want my library to execute something by default, when my program starts. I want it to contain a set of functions that are executed only when they are called explicitly.
In the step 4, it is written that I need to "Compile main.cpp and add the library from step 2", but I have already compiled the library on the step 2. Should I compile it one more time?
What does "in this case 'myfile.o'" mean? What exactly should I do with "myfile.o" in this case?
On the step 4 it is written "If you don't add this library, you'll get a error message". But what does "to add library" mean? On step 3 I put #include "mylibrary.h" into the main.cpp, so I have added the library? Or I need to do something more to add the library?
Could you please help me to understand the answer?
ADDED: I think I need to use Eclipse to generate .a, .lib, .so, or .dll files? Does anyone know how I can do it and what exactly I should generate?
For this example, consider a "library" which provides the factorial function. For simplicity, I use free functions.
// factorial.h
int factorial(int input);
// factorial.cpp
#include "factorial.h"
int factorial(int input) {
if(input > 0) return input * factorial(input - 1);
else if(input == 0) return 1;
else return 0;
}
Now compile these files to generate a factorial.o, but do not link. (Configure the Eclipse build command accordingly. If using gcc, use the -c and -o flags appropriately. Refer compiler documentation to understand what these flags do.)
Next create a main.cpp (you can actually name it anything you like.)
// main.cpp
#include "factorial.h"
int main() {
// use your library code here to make sure it is usable and working.
factorial(3);
factorial(5);
// etc.
}
Now compile this to a main.o, then link this together with the factorial.o from earlier to generate the executable. You can actually skip the intermediate main.o step, and do both of this in one step with the appropriate compiler options.
Related
I have something that need to link some C++ codes to main Pascal program. I followed this tutorial, now I have:
download.h
#include <iostream>
#include <curl/curl.h>
using namespace std;
// function goes here
int downloadsrc(char* pkg_name){
// do stuff
}
download.pas:
unit download;
{$link download.obj} // fpc may overwrite download.o
Interface
uses ctypes;
function downloadsrc(pkg_name:string):integer;
Implementation
// I leave this empty
end.
My main program:
program myprog;
uses
warn, download, test;
var i:integer;
begin
if ParamCount = 0 then help()
else for i:= 1 to ParamCount do
begin
if ParamStr(i) = 'download' then downloadsrc(ParamStr(i+1))
else if ParamStr(i) = 'test' then test();
end;
end.
I tried g++ to compile .h file, change the output.. but when build the program FPC says that:
download.obj: file not recognized: file format not recognized
Compiling download.pas manually still works.
Am I do something wrong here? Am I need to do some other things, like add a compile flag or modify the code?
FPC, like GCC, uses COFF objects. Make sure your .obj is COFF not OMF.
If you fix that, you probably must also link some C++ runtime library, and declare downloadsrc in a C callable way, and alter the FPC declaration to match (cdecl)
I am just learning c++ and began to watch a youtube tutorial by thenewboston. Unfortunately he is using Code::Blocks while I am using gcc and I do not have the option to create new class files with a button click and so had to manually create them.
I dont understand why the same code in Code::Blocks and gcc will work in Code::Blocks but not gcc. Does gcc require different coding for the same language?
EDIT: I have downloaded and tested in Code::Blocks myself
Other questions talk of how I need to give windows an entry point, but I dont know how to do that.
Test.cpp Code:
#include <iostream>
#include "ClassTest.h"
using namespace std;
int main() {
ClassTest bo;
}
ClassTest.h Code:
#ifndef CLASSTEST_H
#define CLASSTEST_H
class ClassTest {
public:
ClassTest();
};
#endif // CLASSTEST_H
ClassTest.cpp Code:
#include <iostream>
#include "ClassTest.h"
using namespace std;
ClassTest::ClassTest() {
cout << "blah blah" << endl;
}
I'm not quite sure I understand what the question is; I'm going to take it as "how do I get these three files to build into a .exe that I can run from the Windows commmand line?"
The answer is to run something like this on the command line, in the folder with the files:
g++ -c Test.cpp -o Test.o
g++ -c ClassTest.cpp -o ClassTest.o
g++ Test.o ClassTest.o -o Test.exe
The first two commands build each CPP file into an "object file", which isn't a whole program by itself but which contains the compiled version of the code in that CPP file. The last command tells the compiler to paste together the two object files into a program, and resolve all the cross-references between them. (For example, the part where Test.cpp constructs a ClassTest object needs to end up calling the ClassTest constructor code from ClassTest.cpp.)
Code::Blocks is an IDE and works out how to build each source file in your project and link them together by itself. But if you aren't using an IDE, you need to do that in another way. You can either do it manually like this, or you can write a Makefile that will check which code files have changed and rebuild and re-link everything that depends on them when you run the make command, which is how most people do it.
As for "giving Windows an entry point", that probably refers to GUI applications that want to display windows on the screen. For console programs like the one you have written, the "entry point" is main(), and you just print stuff to the command line window. To make actual Windows-style GUI windows of your own, you need to use the Windows API, which I can't tell you much about.
I'm new to cpp in eclipse and trying to mess with simple builds. I have made a basic project which automatically generates build info (no user-defined makefile).
Simple (Working) Case
I made a "Hello World" project called Test (not an empty project). It has one file - Test.cpp with a main() in => builds and runs fine.
Test.cpp
int main() {
// output some stuff
}
Slightly More Complex (Working) Case
I make a new file called Main.cpp. Move the main() function into Main.cpp and make a decleration of a function in main too - void test();
The test() function lives in Test.cpp, which is where I provide the function definition.
Main.cpp
#include <iostream>
void test();
int main() {
// Use test()
}
Test.cpp
#include <iostream>
void test() {
// output some stuff
}
Build it, there are now two .o files in the Debug directory - Test.o and Main.o. This runs fine.
The Problem
Now I try to introduce a third file - Limits.cpp.
Limits.cpp
#include <iostream>
void printLimits() {
// Print out limits for different integer sizes
}
Again I provide a deceleration of this function in Main.cpp.
Main.cpp
#include <iostream>
void test();
void printLimits();
int main() {
// Use printLimits()
}
This time there is no object file created for Limits in the Debug folder => the build fails.
Main.cpp:*line* undefined reference to `getLimits()'
It just looks like the autogenerated build config for the project is duff. I've tried looking around the project properties but I have had no luck. I've tried including the path/file in Include Paths/Include files, other objects, and I've checked just about every other property I can see. This has been frustrating me for two days.
The strange thing about this is case 2. It looks like because Test.cpp was the first file made it always includes this in the build? (even if it is not imported). Where as because Limits.cpp is new and not imported it doesn't generate an object file so it can't link the function.
I could me making an error by needing to include the files but my understanding is if all the object files make it to the linker then all will be well (ie I just need the function declarations when making the object files which is what I have here).
With a "Blank project" it seems to compile all the cpp files even if they are never used so my case above works. (Although, it doesn't work for files in subfolders of src). Looks like its a "feature" of the "Hello world" project type but it's going to drive me crazy knowing there must be a way to get it to do this.
If anyone knows if it is possible to include this file without writing my own makefile (I'm not a makefile guru (yet!)), or let me know if this is not possible with autogen CDT that would be great.
Using MinGW GCC toolchain.
Thanks
I have a big C++ code and I want to integrate this into MATLAB so that I can use it inside my matlab code. If it was a single code making its mex file would have been the best option. But since now it's a code that needs to be compiled and built in order to run, I don't know how can I use the functions in this code.
Is making mex files for the whole code the only option or is there any other workaround? Also I would like some help on how can I make mex files for the whole code and then build it.
For more insight, this is the code I am trying to integrate in matlab http://graphics.stanford.edu/projects/drf/densecrf_v_2_2.zip . Thank You!
First you'll need to compile the library (either static or dynamically linked). Here are the steps I took on my Windows machine (I have Visual Studio 2013 as C++ compiler):
Generate Visual Studio project files using CMake as described in the README file.
start VS, and compile densecrf.sln solution file. This will produce a static library densecrf.lib
Next modify the example file dense_inference.cpp to make it a MEX-function. We'll replace the main function with:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
..
}
and instead of receiving arguments in argc/argv, we'll obtain the parameters from the input mxArray. So something like:
if (nrhs<3 || nlhs>0)
mexErrMsgIdAndTxt("mex:error", "Wrong number of arguments");
if (!mxIsChar(prhs[0]) || !mxIsChar(prhs[1]) || !mxIsChar(prhs[2]))
mexErrMsgIdAndTxt("mex:error", "Expects string arguments");
char *filename = mxArrayToString(prhs[0]);
unsigned char * im = readPPM(filename, W, H );
mxFree(filename);
//... same for the other input arguments
// The example receives three arguments: input image, annotation image,
// and output image, all specified as image file names.
// also replace all error message and "return" exit points
// by using "mexErrMsgIdAndTxt" to indicate an error
Finally, we compile the modified MEX-file (place the compiled LIB in the same example folder):
>> mex -largeArrayDims dense_inference.cpp util.cpp -I. -I../include densecrf.lib
Now we call the MEX-function from inside MATLAB:
>> dense_inference im1.ppm anno1.ppm out.ppm
The resulting segmented image:
An alternative approach can be to compile your large C++ code into a shared library (.dll or .so depending on your OS) and then load this library in Matlab using loadlibrary.
Once the library is loaded you can call each and every one of its API functions using calllib.
Example: assuming you are working in Linux environment and you have you c++ code in a file myLib.cpp with a header file myLib.h, then you can use g++ to create a shared library
$ g++ -fPic -c myLib.cpp
$ g++ -shared -o myLib.so myLib.o
Now, in Matlab, you can load the library (assuming the .so file and .h files are in your matlab path)
>> loadlibrary( 'myLib', 'myLib.h' );
main.cpp
#include <iostream>
#include <string>
using namespace std;
void echo(string);
int main()
{
echo("hello");
cout << "Hello world!" << endl;
return 0;
}
print.cpp
#include <iostream>
#include <string>
void echo(string code){
cout << code;
}
After compiling the code in code blocks 12.11, it gives me that error:
undefined reference to `echo(std::string)
I use windows 7 x64.
I have added the directory; Project>build options > search directories and added the current working directory.
All the files are in one console project in code blocks
I believe you should read up a bit more on namespaces usage. You are missing std in print.cpp.
Generally, while starting to learn cpp or getting a grip of the language you should always try writing full names of the classes along with the namespaces. Eventually with practice and some oversights (like now) you will learn why you really need them. In a nutshell namespaces are great:
When you are writing code over multiple files
Compartmentalize your code into separate blocks.
Also, using namespace std; should be used within cpp files mostly (otherwise headers get mangled up.
Anyways, try changing your code to this:
#include <iostream>
#include <string>
void echo(std::string code){
std::cout << code;
}
Then your results will look like this:
> g++ main.cpp print.cpp -o a.out
> ./a.out
helloHello world!
You should get more than that linker error, since you use string without any namespace in your print.cpp file. And if that source file doesn't compile it can't be linked with, and you will get the linker error you have.
Change to e.g.
void echo(std::string code) { ... }
And you do try to link with the object file created from print.cpp ?
I know this is old, but for anyone looking to solve this issue, the following may be a solution for you. If you have g++ follow c++ 11 under project->build options (check your options anyway) then you must check that box for all files you make in the project for the error to be cleared up. I had that annoying undefined reference thing too but now it is gone!
Try "Project/Properties/Build Targets tab". There you should find "Build target files" field. In that filed find "print.cpp" and click the checkbox (now the compiler will build print.cpp).
Some usefull information on Project management in CB
http://www.codeblocks.org/docs/main_codeblocks_en.html
When dealing with strings in C++ its best to sue std::string and your code seems to be wrong with a changes like using std::cout instead of plain cout another thing you need to be careful is linking your files especially files in different directories you need to tell code blocks were to find this print.cpp by going to build option and go for the search tab directory and point to where print.cpp is other wise the other approach is to just build a project which will have the main.cpp and and then add print.cpp class to current project I hope this will be of some help