views:

375

answers:

2

Hey guys i have some quick questions on windows dll.

Basically i'm using the ifdefs to handle the dllexport and dllimport, my question is actually regarding the placement of the dllexports and dllimports as well as extern keyword.

I am putting the dllimports/dllexports on the header files but do I have to put the dllexport and dllimports on the actualy definition?

What about for typedefs?

Do i put the dllimport/dllexport in front? as in

dllexport typedef map<string, int> st_map

Also regarding the extern keyword I have seen it being used like this:

extern "C" {

dllexport void func1();

}

I have also seen it being used like this:

extern dllexport func1();

One includes the "C" and the other does not, my question is what is the difference and do i need to use it? If I do then do I use it for both dllexport and dllimport also do I have to use it on both the header file declarations and the definitions?

My project is going to be shared library, it contains several class files which I want to export, some typdefs i want to export and some global functions which I also want to export all into a dll.

Anyone enlighten me please?

EDIT:

Okay i thought i'll post a small extract of what i've done, also notice that I am building the library for both linux and windows so I do a check for that:

mydll.h

#ifdef WINDOWS
#   ifdef PSTRUCT_EXPORT
#   define WINLIB __declspec(dllexport)
#   else
#   define WINLIB __declspec(dllimport)
#   endif
#else
#  define WINLIB
#endif

WINLIB void funct1();

Now in the source code:

mydll.cpp

#define PSTRUCT_EXPORT

void funct1() <---- do i need to add WINLIB in front of it? 
                      Or is doing it in the header enough?
+1  A: 
  1. typedefs do NOT need a dllimport/dllexport, it's just a definition
  2. dllimport/dllexport are not standard, think of defining a macro for other platforms/compilers
  3. also take care of the calling convention (cdecl,stdcall,...) used otherwise you'll run into problems (if you need to be interoperable with Visual basic use stdcall)
  4. enclose within extern "C" so that your lib can be used from within C++ programs, use #ifdef __cplusplus to keep it only visible to C++.

Have a look at different OpenSource libs. There you'll find plenty of examples on how making a good library header. There could be issues with name decoration in the case of C++ without the extern "C".

jdehaan
Most of the things I am putting in the dll are classes so I mainly want this to be compiled mainly under c++ so should I avoid exter "c"?
iQ
In this case yes - you must not use extern "C". BUT be aware that because of name decoration you force others to use the same compiler to use your lib. To avoid this you could provide a C library and a C++ wrapper for it that can be integrated as source code in customer's projects
jdehaan
+2  A: 

First, you don't need to import or export typedefs. As long as they're in the header files that both sides use, you're good. You do need to import/export functions and class definitions.

Presumably you use the same header files for both the importing and exporting code, so you could do some makefile magic to define a preprocessor macro on each side, then do something like this:

#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif

extern MYAPI void func1();
class MYAPI MyClass {
    ...
};

Regarding C vs. C++ functions, you can do this:

#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif

extern _croutine void function_with_c_linkage();

Make sure you import this header file from your C++ source file (containing the implementation of this function) or the compiler won't know to give it C linkage.

Graeme Perrow
Okay i've got something very similiar except the the extern keyword bit. I have similiar macros defined in all my class files.So the extern is used to provide support for C compilers? My project is mainly C++
iQ
do i also need to add the dllimport/export statements in the definition?
iQ
The only reason you'd need the extern "C" stuff is if you're trying to link a C++ function from C code. Basically, you can ignore the extern "C" stuff until you get linker errors.
Graeme Perrow
You can either #include the header file into the source file *or* put the dllexport/import stuff on the definition of the function. I usually #include the header file.
Graeme Perrow