I'm reasonably new to C++ but have just inherited a set of 20+ C++ solutions that work together to create an application suite. I have a class held in a singular .cpp file that can be used to connect and communicate with an SQL database, and I want to make all of the solutions be able to use this class.
I have put the sql.cpp file in a directory called "Shared" that already existed. But where in each project do I include the file? I have tried including it in the stdafx file but that caused endless compiler errors. I have tried including it in each individual .cpp file that uses it within the project but as soon as I include it in more than one I get "already defined in obj" errors. I have also tried creating a separate .h file to instantiate the class and including that, but it seems to not find the .cpp file as I get unresolved external errors.
I hope I have explained that well enough - could anyone shed some light on this subject?
Thanks!
You don't include the cpp file.
First, take the functions prototype and create header file
if your Sql.cpp code is
bool Open(char* name)
{
//do something
}
void Close(char* name)
{
//do something else
}
your Sql.h header should be:
(you put only functions you want to call from outside the file)
#pragma once
bool Open(char* name);
void Close(char* name);
Second, I assume you better make a library (static library is the simplest, but better a shared or DLL depending your OS) and link to it from all the projects need it.
you can use the object file as well as static library if it not depends on anything else.
EDIT:
on Windows DLL:
On windows Static lib
how to build static library in linux
how to build shared library in linux
Related
I am facing the following problem:
I have a project which contains math classes (.h and .cpp files).
I want to use these classes in a different project (not int he same solution) but I can't.
In the new project I add a path to the include files of my math project. When I try to #include them it works and I can see my classes but upon trying to use them I get "Unresolved external". I haven't created a .dll or a .lib so I really don't know what's causing this.
If you have any suggestions, I`ll appreciate it.
Thank you very much in advance.
When I try to #include them it works and I can see my classes but
upon trying to use them I get "Unresolved external". I haven't created
a .dll or a .lib so I really don't know what's causing this.
That you have not created a library is precisely the reason why you get the error. The compilation units in your new project ("the *.cpp files") include the headers for your classes and make use of the class definitions, but the definitions of the members are missing.
For example, let's say you have a file called "c.h" in your old project:
#ifndef C_H
#define C_H
class C
{
public:
C();
void f();
};
#endif
Some *.cpp file in your new project includes the header and uses the class:
#include "somepath/oldproject/c.h"
void someFunction()
{
C c;
c.f();
}
This compiles fine, but it will cause linker errors, because the definitions of C::C and C::f will be missing.
Now, the clean solution to this is certainly not adding somepath/oldproject/c.cpp from your old project to your new project, although that would fix the linker error, but to employ a library-based approach. Turn your math classes into a library project, let's call it "Math Utils", which produces a *.lib file (as you seem to be on Windows), for example math-utils.lib. Add the library's include and release path to your global include and library paths. Then add the math-utils.lib file to the new project's linker dependencies.
And change the code in your new project to:
#include <math-utils/c.h>
void someFunction()
{
C c;
c.f();
}
Do the same thing in the old project! You will end up with three different projects. Two application projects and one library project, the former two depending on the latter.
Creating your own libraries for the first time can be a bit intimidating, but the benefits are worth the trouble.
See also The Linker Is not a Magical Program.
I'm trying to access functions from another file for use inside my class definition:
// math.cpp
int Sum(int a, int b){
return (a + b);
}
// my_class.cpp
#include <math.cpp>
#include <my_class.h>
int ComputeSomething() {
...
return ::Sum(num1, num2);
}
Despite my best efforts, I can't get the compiler to spit out anything outside the likes of ::Sum has not been declared or Sum was not declared in this scope.
I'm trying to wrap my head around code organization in C++, any help appreciated.
It might be worth noting that I'm programming for Arduino.
To be able to access functions from a user-defined library, best divide that library into a .h (or .hpp) and a .cpp file. I understand you have actually done this, but tried various options – among them the inclusion of the .cpp file – for the sake of finding a solution.
Still, to ensure things work as expected, the declarations of functions and classes should go into the .h file, best protected by something like
#ifndef MY_H_FILE
#define MY_H_FILE
/* ..Declarations.. */
#endif
Then to include the .h file (I'll assume it's named my.h), either use
#include "my.h" // path relative to build directory
or
#include <my.h> // path relative to any of the include paths
The latter only works if my.h is found on an include path previously known to the compiler (e.g. what is specified using the -I command line option in GCC). The former works if the path to the .h file given is relative to the directory your are building from.
Finally, do not use a file name that can be confused with a system library (such as "math.h"), especially if you are using the <...> syntax, as the include path will definitely include the system library header files.
Have you followed the instructions given here?
User-created libraries as of version 0017 go in a subdirectory of your
default sketch directory. For example, on OSX, the new directory would
be ~/Documents/Arduino/libraries/. On Windows, it would be My
Documents\Arduino\libraries. To add your own library, create a new
directory in the libraries directory with the name of your library.
The folder should contain a C or C++ file with your code and a header
file with your function and variable declarations. It will then appear
in the Sketch | Import Library menu in the Arduino IDE.
I just started learning C++ with Dev C++ as my IDE. One of the tutorials I'm using has a page in it about compiling a program made up of multiple files. It's simple stuff at this point, I have one file with a function in it, and the other file has all the other required code to call the function and output the results. The problem is that the tutorial doesn't tell me how to join these files so I can compile the program and have it work. There's seems to be multiple ways of doing this and I'd like them all but I'm mainly look for the simplest one right now.
I should also mention that I'm new at this so please try and keep your explanations simple and understandable.
In general, you would add both .cpp files to your project under the same target. It IDE will automatically add both files to the build and link them together.
That said, Dev-C++ is very, very old and unmaintained. It has not seen updates in several years. I strongly urge you to use a different IDE. There are many to choose from, including a fork of Dev-C++ called wxDev-C++. I'd actually recommend Code::Blocks or Visual Studio Express, which are both much more modern and have better support for debugging and many other features.
I am not sure of Dev-C++, but the concepts remain the same. So, here is how you can try to get both the files to work together
Each C++ file is a compilation unit - meaning, the compiler will convert one .cpp / .cxx file to one .obj / .o file (on Windows and Linux (or any Unix)) respectively
The obj files, called the object files contain the machine code (am skipping few internal details here) for the classes and functions present in that particular file
If you want to access the functions present in a different compilation unit, you need to link those two object files
Linking is a term that is used to, well, link two object files
There is a separate process (other than the compiler) which does the linking of the object files
So,in your case, you need to use the dev-c++ compiler and create separate object files
Then using the linker you link both the object files to create the final executable
If there are functions that exist in the .cpp files that you want to reference, you use the header files. The header files contain the function/class declarations. The .cpp files will have the implementations. So, in one of your .cpp file, (say) A.cpp, you include the header B.hpp and use the functions in the B.hpp file. The inclusion of headers will tell the compiler that the function declarations exist elsewhere and that the linker will take care of stringing all these references together to create the final executable.
Hope this helps, else, please don't hesitate to mention the files you are using and I can suggest how to link both the .cpp files together.
You must include the other files by using the #include preprocessor directive
in the top of the file where you have the main() function
For example:
#include "filename.h"
...
/* rest of code containing main function goes here */
...
#include "path/filename.c"
main
{
...
...
...
}
I have a Visual C++ solution with 2 projects AlgorithmA & AlgorithmB and both share a common header file RunAlgo.h with the class declaration. Each project in the solution has its own unique implementation for the header file.
I am trying to compile a DLL out of the common header file RunAlgo.h and add reference to this DLL in the projects AlgorithmA & AlgorithmB. I have then included separate RunAlgo.cpp definition file in both my projects. The problem is that I am getting linker errors while compiling the new DLL project which has only the header file.
So, the question is
Can a header file with only class declaration be compiled into a DLL (Similar to class library containing an Interface in C#)?
For the above scenario, is there a better approach to reuse the common Header file among projects?
Should the above method work (re-check my code?)
1 & 3: No, that doesn't make sense in C++.
Libraries (dynamic or otherwise) are only used during linking. During compilation declarations must be visible to the compiler in source-code form. This is why, for example, you have to explicitly #include standard library headers in addition to linking against the standard library.
2: What you're already doing is basically the only solution. Put the common header files in their own directory, and add that directory to the include path of each of the two projects.
Can a header file with only class
declaration be compiled into a DLL
No, headers typically include only declarations. Declarations when compiled don't produce any machine code, so resulting DLL would be empty.
For the above scenario, is there a
better approach to reuse the common
Header file among projects?
Reusing header is fine. In fact, every library has it's set of headers that you need to include in projects using that library.
I don't know much Visual C++, but I think you could make third project, containing common parts (i.e. RunAlgo.h header), and mark it as a dependency for AlgorithmA and AlgorithmB projects.
To 1.:
No, free-standing header files never end up in a dll. Header files are included in implementation files and that's how they are compiled. Header files are usually distributed along with a dll or library if you want to allow third parties to link against it.
To 2.:
Why don't you declare an abstract base class with the interface for the algorithm and provide two different implementations by defining two subclasses (AlgorithmA and AlgorithmB) deriving from the base class? I don't get why you want to different DLLs.
To 3.:
No, it shouldn't. See point 1.
Use 2 namespaces in C++ to write 2 different implementation with the same header file
namespace ImplementationA
{
}
namespace ImplementationB
{
}
When you want to use 1st implementation
using implementationA;
or
implementationA::function1();
I am making a static library of my own. I have taken my code which works and now put it into a static library for another program to use. In my library I am using another static library which I don't want the people who will be using my API to know. Since, I want to hide that information from them I can't tell them to install the other static library.
Anyway, I used the command line Lib.exe to extract and create a smaller lib file of just the obj's I used. However, I get a bunch of LNK4006 :second definition ignored linker warnings for each obj I use followed by LNK4221 no public symbols found;archive member will be inaccessible.
I am doing this work in vs2008 and I am not sure what I am doing wrong.
I am using the #pragma comment line in my .cpp file
I have also modified the librarian to add my smaller .lib along with its location.
my code simply makes calls to a couple functions which it should be able to get from those Obj file in the smaller lib.
All my functions are implemented in .cpp file and my header just have the includes of the third party header files and come standard c++ header files. nothing fancy. I have actually no function definitions in there atm. I was going to put the API definition in there and implement that in the .cpp for this static lib that i was going to make. However, I just wanted to build my code before I added more to it.
I did read http://support.microsoft.com/default.aspx?scid=kb;EN-US;815773 but it did not provide a solution.
Even if you extract all objects from the other library and put them in your own library, your users will still be able to see what's in your library and thus see all the object names. In many cases the names of the objects will reveal what's actually the other library you are using.
Instead of distributing your library as a static library, consider distributing it as a DLL. In the DLL you can easily hide all the underlying things and only make public what you want to make public.