2

I am using a mingw compiler and code blocks IDE. I am facing a problem in which I don't understand how come my dll exports every function without me even using __declspec(dllexport) with these functions. Here are the two sample files, main.h and main.cpp:

main.h:

#ifndef __MAIN_H__
#define __MAIN_H__
#include windows.h

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
#endif

void SomeFunction(const LPCSTR sometext);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

main.cpp:

#include "main.h"


void SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL fxn Message", MB_OK | MB_ICONINFORMATION);
}

bool flag = false;

extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;
        case DLL_PROCESS_DETACH:
            // detach from process
            break;
        case DLL_THREAD_ATTACH:
            // attach to thread
            break;
        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }

    flag = true;

    return TRUE; // succesful
}

In this example, SomeFunction is exported and I am able to dynamically call it from an application externally, although I haven't prototyped it as

void __declspec(dllexport) SomeFunction(const LPSTR sometext);

Not only this, even the global variable flag is exported in the auto generated .def file.

What is happening here? Please help and correct me if I am making a technical mistake.

Haziq
  • 21
  • 3
  • possible duplicate of [How to tell the MinGW linker not to export all symbols?](http://stackoverflow.com/questions/2810118/how-to-tell-the-mingw-linker-not-to-export-all-symbols) – laalto Sep 25 '14 at 05:21

2 Answers2

3

The MinGW linker makes all symbol public unless you make them hidden by default. This can be overridden, from the GCC man-page:

-fvisibility=default|internal|hidden|protected

...
 A good explanation of the benefits offered by ensuring ELF symbols
           have the correct visibility is given by "How To Write Shared
           Libraries" by Ulrich Drepper (which can be found at
           <http://people.redhat.com/~drepper/>)---however a superior solution
           made possible by this option to marking things hidden when the
           default is public is to make the default hidden and mark things
           public.  This is the norm with DLL's on Windows and with
           -fvisibility=hidden and "__attribute__ ((visibility("default")))"
           instead of "__declspec(dllexport)" you get almost identical
           semantics with identical syntax.  This is a great boon to those
           working with cross-platform projects.
Maister
  • 4,978
  • 1
  • 31
  • 34
  • 1
    I have tried to add the attribute -fvisibility=hidden to the compiler options, but the build log says: C:\Test\caught\main.cpp|7|warning: visibility attribute not supported in this configuration; ignored| ||=== Build finished: 0 errors, 3 warnings ===| And the function is again exported. Please explain what do you mean by gcc man page. I haven't over ridden it there. Thanks. – Haziq Feb 18 '11 at 13:20
  • A man page is a manual in the Unix world. I think this should be it: http://linux.die.net/man/1/gcc. – Maister Feb 19 '11 at 13:26
0

I don't know the MinGW linker or CodeBlocks, but the other way a function can be exported is through a .def file. Do you have a .def file that lists SomeFunction that you are passing into the linker?

(This looks like the VC++ DLL template, which does IIRC include a .def file with those exports)

Rup
  • 33,765
  • 9
  • 83
  • 112
  • No, I don't use a .def file myself, but the IDE automatically generates it. It has an option to disable automatic generation, but still it exports SomeFunction even if I use this option. – Haziq Feb 18 '11 at 11:15