NO

Author Topic: Build a dll without __declspec(dllexport)?  (Read 3841 times)

opaque

  • Guest
Build a dll without __declspec(dllexport)?
« on: April 02, 2020, 10:43:40 AM »
I forgot to add __declspec(dllexport) and write the code for the dll just like normal program. Does Pelles C support build a dll and automatically exported all functions and types from it? MinGW has this option.

http://www.mingw.org/wiki/sampledll

Quote
Building and using a DLL without the dllexport/dllimport attibutes

If you pass the -no-undefined and --enable-runtime-pseudo-reloc options to the linker, you don't have to add dllimport or dllexport attributes to the source code that the DLL is made with ; all functions are imported/exported automatically by default, just like in unices.

I have successfully build a dll from my code with MinGW and program linked to it worked properly.

opaque

  • Guest
Re: Build a dll without __declspec(dllexport)?
« Reply #1 on: April 02, 2020, 10:45:42 AM »
When I posted this thread it's error with "Call to undefined method Akismet::setAuthor()". Fortunately, the thread was posted successfully.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Build a dll without __declspec(dllexport)?
« Reply #2 on: April 02, 2020, 12:02:13 PM »
PellesC doesn't have the GCC option.
If you don't specify any exported symbol the export table in the PE file will be empty.
If you don't want modify all your DLL code you can build a DEF file with functions you want to export and relink the DLL objects adding the DEF file.
For better instructions please refer to the help for polink option /DEF:filename
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

opaque

  • Guest
Re: Build a dll without __declspec(dllexport)?
« Reply #3 on: April 02, 2020, 05:33:23 PM »
PellesC doesn't have the GCC option.
If you don't specify any exported symbol the export table in the PE file will be empty.
If you don't want modify all your DLL code you can build a DEF file with functions you want to export and relink the DLL objects adding the DEF file.
For better instructions please refer to the help for polink option /DEF:filename
If my code doesn't specify it does Pelles C use CDECL or STDCALL by default? I have to know this to prepare the .def file.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Build a dll without __declspec(dllexport)?
« Reply #4 on: April 02, 2020, 10:26:13 PM »
If my code doesn't specify it does Pelles C use CDECL or STDCALL by default? I have to know this to prepare the .def file.
This is not related to the export qualifier __declspec(dllexport). This extended qualifier simply puts the address of your function in the export table of the PE executable independently from the calling convention.
You can specify the calling convention for 32bit executables on function by function basis, using the qualifiers __stdcall or __cdecl, or globally defining the default calling convention. For 64bits executables the calling convention is fixed and is the MS 64bits ABI.
The default calling convention can be set on the compiler command line with the switches /Gr and /Gz, or setting it in the IDE project options, compiler tab.
You must specify in an header file the prototype of your exported functions, eventually adding the calling convention, __stdcall or __cdecl, and include it in the modules of the executable that loads the DLL.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

opaque

  • Guest
Re: Build a dll without __declspec(dllexport)?
« Reply #5 on: April 04, 2020, 09:27:41 AM »
If my code doesn't specify it does Pelles C use CDECL or STDCALL by default? I have to know this to prepare the .def file.
This is not related to the export qualifier __declspec(dllexport). This extended qualifier simply puts the address of your function in the export table of the PE executable independently from the calling convention.
You can specify the calling convention for 32bit executables on function by function basis, using the qualifiers __stdcall or __cdecl, or globally defining the default calling convention. For 64bits executables the calling convention is fixed and is the MS 64bits ABI.
The default calling convention can be set on the compiler command line with the switches /Gr and /Gz, or setting it in the IDE project options, compiler tab.
You must specify in an header file the prototype of your exported functions, eventually adding the calling convention, __stdcall or __cdecl, and include it in the modules of the executable that loads the DLL.

Because I don't write the .def file myself. I got it generated from MinGW when compiling the dll with MinGW. The generated .def file is decorated with @ so I think it's STDCALL.

Yes, it's a 64 bit DLL. But I also want to build for 32 bit.

IMHO, being able to build a dll without dllexport/dllimport is very useful. I think Pelles C should support it.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Build a dll without __declspec(dllexport)?
« Reply #6 on: April 04, 2020, 04:40:22 PM »
Because I don't write the .def file myself. I got it generated from MinGW when compiling the dll with MinGW. The generated .def file is decorated with @ so I think it's STDCALL.
Yes, it's a 64 bit DLL. But I also want to build for 32 bit.
IMHO, being able to build a dll without dllexport/dllimport is very useful. I think Pelles C should support it.
I see a lot of confusion here, and honestly don't understand your point.
Lets consider each options.
  • MINGW is based on gcc, that is mainly used on*nix systems where DLL concept (called *.so shared libraries) is completely different, by default exports all non static symbols found in object files without any specific indication.
  • Gcc by default doesn't use the DEF file at all.
  • The behavior of gcc is many times annoying, because expose to the DLL interface even internal inter module symbols that you want eventually keep reserved, and don't want be accessed externally to avoid any unwanted hacking of your code (that's why it isn't a good moveā€¦).
  • Software that don't use __declspec(dllexport) nor a DEF file isn't interchangeable with other compilers and can't be compiled with any other MSC compliant compilers.
  • PELLESC is a C99-C11 compliant compiler that also supports only MS extensions.
  • MS don't export automagically all symbols, but require the user to specify which symbols to export by means of a definition file or the extended specifier __declspec(dllexport). The reasons are that explained before.
  • Adding an extended specifier, __declspec(dllexport), isn't a big trouble at all, and is silently accepted even by MINGW. Normally the procedure used to define it, letting the code to be compiled also for platforms different from WINDOWS, is the following:
Code: [Select]
#ifdef _WIN32    //If compiling in MS environment define export specifier
#define EXPORT __cdecl(dllexport)
#else
#define EXPORT    //For all other OS ignore it
#endif

int EXPORT foo(void)
{
    ...
}
  • The decoration of symbols, with characters added to the name of the symbol, follows different definitions for 32 and 64 bits.
    Specifically in a 32bits environment. where more calling conventions exists, when the symbol is decorated with a post-fix '@' followed by one or more decimal digits indicates a __stdcall calling convention, and the decimal number specify how many stack bytes are used for argument passing.
    In 64bits environment exist only one calling method used for everything, normal and variadic functions, and all symbols are decorated with a postfixed '@' character again followed by decimal digits having the same meaning as in the 32bits case.
  • Who decide which calling convention uses a function is you and no one else, when declaring the function. So you must be aware of which type it is.
    Who instead don't know the calling convention type is the program that will use your DLL functions. To make it aware you include in it an header file with functions declarations. This header shall specify the calling convention.
    Once again the export mechanism don't care of what the symbol is and what convention it uses. The export process simply insert in the export table the symbol name and its address. No other information are stored.
    So it is more mandatory, than suggested, when writing function definitions for DLL export, to add a full qualification of function, including the calling convention.
    This because, once again, exporting a symbol through the export table (also known as jump table) mechanism don't give any qualification information to the loader when linking the DLL for run.
  • The qualifier __declspec(dllimport), opposing to __declspec(dllexport), is optional.
    When specified the loader will link the call directly to the function address found in the export table.
    If not specified the loader will call the local import table entry, where the code will find a jump instruction to the function address inside the DLL. The program works anyway.

In the end if you like more the gcc behavior use it, it is a gcc compiler private extension, almost never available on compilers specific for MS OS.
I hope to have made it more clear now.
« Last Edit: April 04, 2020, 09:12:09 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide