I am extremely confused about libraries and have been having trouble understanding them with google. Basically I want to create a library so that I can use a bunch of functions from another file without all of the libraries' contents being seen. EG:
library code:

class test
{
private:
int num;
public:
test(int a):num(a){}
int num(){return a;}
};

header code:

class test
{
private:
int num;
public:
test(int a);
int num();
};

cpp file code:

#include "theheaderfile.h"
#include <iostream>
using namespace std;
int main()
{
test tst(5);
cout<<tst.num();
}

What kind of library should I use and how do I implement it on my cpp files? (I am using Code::Blocks IDE)

Recommended Answers

All 11 Replies

You can not hide the class declaration from the application program, but you can put the code that implement the class methods into a library so that the implementation code is hidden from the application program.

There are two kinds of libraries: static and dynamic. Static libraries have *.lib extension and are linked into the application program when the program is compiled and linked. This takes up the most disk space because each application program has a complete copy of the code it uses in the library.

Dynamic libraries on MS-Windows have *.DLL extension. When you compile a DLL the compiler will also generate a *.lib file that only contains the information compilers need to resolve function and data address while compiling the application program. There is only one copy of the code in memory regardless of how many application programs use it, so DLLs require the least amount of memory.

So it seems like I should use a DLL, but how do I use a DLL?

So it seems like I should use a DLL, but how do I use a DLL?

That's operating system specific...Which operating system are we talking about here?

Windows XP, but I want compatibility up to and including windows 7 and backwards compatibility for windows 2000. Also I am using Code::Blocks which seems to have some kind of predefined DLL style project?

Could I just have an example, for example how to properly turn my above sample code into a dll?

So it seems like I should use a DLL, but how do I use a DLL?

Both static libraries and DLLs are used alike from the application program point of view. They both link to a *.lib file. To use a DLL all you have to do is copy it to one of the folders in the PATH environment variable or in the folder where the application *.exe is located.

If you do not have the *.lib file for a given DLL there is another way to link which does not require the *.lib file. Check out LoadLibrary() and GetProcAddress()

So how exactly would I write a dll and implementation file for the three blocks of code in my first post in this thread?

So how exactly would I write a dll and implementation file for the three blocks of code in my first post in this thread?

For exporting classes, it is better to create and destroy objects in DLL itself to avoid compiler crash (if main app is compiled differently from DLL(s)). So export method for creating object and destroying objects in DLL as C-style.

something like:

class Library{
    //all methods goes here
}

extern "C"{
    Library* createObject(){
        return new Library();
    }
    
    destroyObject(Library* lib){
        delete lib;
        lib=NULL;
    }

}

Check MSDN entry on making DLLs

So, just for clarification, this would work (though it is missing some useful stuff, such as header guards)?:

this file is compiled as a dll:

class test
{
private:
int a;
public:
__declspec(dllexport) test(int a);
__declspec(dllexport) int num();
};
test::test(int a)
{
(*this)->a=a;
}
int test::num()
{
return a;
}

this is a header file to be used to reference the dll:

class test
{
private:
int a;
__declspec(dllimport) test(int a);
__declspec(dllimport) int num();
};

and this as an implementation cpp file:

#include "mydllheader.h"
#include <iostream>
using namespace std;
int main()
{
test tst(5);
cout<<tst.num();
return 0;
}

Exporting a class is something that is pretty hard to do correctly. I don't recommend you try it. In general, I have not seen anyone do it on Windows (in *nix systems it's a different story). Generally, the idea is to export a factory function (and the corresponding destroying function) to handle the create/destroy of the object, and then make all member functions 'virtual' such that you get all the member functions exported for free. But, even when doing that, you still need to worry about a lot of ABI issues (ABI: Application Binary Interface). This is not an easy task (it literally took me 3 years to figure it out for my own purposes, as a little side project, of course).

Read this article, it's a pretty good start to understanding the issues involved.

The easiest solution, really, is to use only a C-style interface for your DLL. With that, your code could look like this:

In the test.h for both the DLL and the application:

#ifdef WIN32
  #ifdef COMPILING_THE_LIBRARY
    #define DLLFUNCTION __declspec(dllexport) __stdcall
  #else
    #define DLLFUNCTION __declspec(dllimport) __stdcall
  #endif
#else  //for *nix systems (no need for anything special)
  #define DLLFUNCTION
#endif

class test; //forward-declaration.

extern "C" {

test* DLLFUNCTION CreateTest(int aA);

void DLLFUNCTION DestroyTest(test* t);

int DLLFUNCTION TestNum(Test* t);

};

In the test.cpp for the DLL:

#include "test.h"

class test
{
  private:
    int a;
  public:
    test(int a);
    int num();
};

test::test(int aA) : a(aA) { }

int test::num()
{
  return a;
};

extern "C" {

test* DLLFUNCTION CreateTest(int aA) {
  return new test(aA);
};

void DLLFUNCTION DestroyTest(test* t) {
  delete t;
};

int DLLFUNCTION TestNum(Test* t);
  return t->num();
};

};

And, in your application:

#include "test.h"
#include <iostream>
using namespace std;

int main()
{
  test* tst = CreateTest(5);
  cout << TestNum(tst);
  DestroyTest(tst);
  return 0;
}
commented: this is good one! +13

Thank you! that is exactly what I was looking for. I am also probably going to turn the class into a struct and just pass a struct to each function that would normally be part of that class, ie:

//what i was going to do:
class test{
private:
int a;
public:
int dosomething();
int dosomethingelse();
};
//what I am going to do:
struct test{
int a;
};
test *__declspec(dllexport) __stdcall NewTest();
int __declspec(dllexport) __stdcall dosomething(test *);
int __declspec(dllexport) __stdcall dosomethingelse(test *);
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.