mingw __dllexport__

librik@panix.com librik@panix.com
Thu, 14 Nov 2002 15:11:06 -0500 (EST)


> For gcc I'm going to change the windows DLL function declarations in
> gmp.h from "__declspec(dllexport)" to "__declspec(__dllexport__)", in
> order to keep out of what is, strictly speaking, application
> namespace.
> 
> Does the same or similar work for Microsoft C?  What about Borland C?


No.  Microsoft Visual C requires __declspec(dllexport).  Unlike
in Borland C, the _export keyword is no longer a legal synonym.

For Microsoft Visual C, the current use of __GMP_DECLSPEC in
gmp-h.in is correct.  (Remember that it was wrong in the original
GMP 4.0, and you moved it to the beginning of the declaration to
make it right.)  Also, the form that you use is correct for _MSC_VER:
   #if defined (__GNUC__) || defined (_MSC_VER) || defined (__BORLANDC__)
   #define __GMP_DECLSPEC_EXPORT  __declspec(dllexport)
   #define __GMP_DECLSPEC_IMPORT  __declspec(dllimport)
   #endif

The syntax of __declspec(dllexport) requires that it go at the
beginning of the declaration.  Here's an extract from the MSDN
documentation:

   __declspec ( extended-attribute ) declarator

   extended-attribute
   allocate(segname)
   dllimport
   dllexport
   naked
   noreturn
   nothrow
   novtable
   property({get=get_func_name|, put=put_func_name})
   selectany
   thread
   uuid(ComObjectGUID)

   ....<snip>....
   The __declspec keywords should be placed at the beginning of a
   simple declaration. THe compiler ignores, without warning, any
   __declspec keywords placed after * or & and in front of the
   variable identifier in a declaration.

   A __declspec attribute specified in the beginning of a user-defined
   type declaration applies to the variable of that type. For example:

       __declspec(dllimport) class X {} varX;

   In this case, the attribute applies to varX. A __declspec
   attribute placed after the class or struct keyword applies to
   the user-defined type. For example:

       class __declspec(dllimport) X {};

   In this case, the attribute applies to X.

   The general guideline for using the __declspec attribute for
   simple declarations is as follows:

       decl-specifier-seq init-declarator-list;

   The decl-specifier-seq should contain, among other things,
   a base type (e.g. int, float, a typedef, or a class name),
   a storage class (e.g. static, extern), or the __declspec
   extension. The init-declarator-list should contain, among
   other things, the pointer part of declarations. For example:

       __declspec(selectany) int * pi1 = 0;
                    //OK, selectany & int both part of decl-specifier
       int __declspec(selectany) * pi2 = 0;
                    //OK, selectany & int both part of decl-specifier
       int * __declspec(selectany) pi3 = 0;
                    //ERROR, selectany is not part of a declarator

   Example

   The following code declares an integer thread local variable
   and initializes it with a value:

   // Example of the __declspec keyword
   __declspec( thread ) int tls_i = 1;


In short, for Microsoft Visual C++, don't change __declspec(dllexport).

- David Librik
librik@panix.com