This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with flag -fvisibility=hidden and share library


Hi José,

> Hello, "I must"(the  Makefile of my library does obtain the flags for
> to compile from other Makefile , I can't to avoid this process ) to
> use the flag -fvisibility=hidden in the compilation of my share
> library, but this make that I have  problems with the use of the
> library , exist someone form , for example using macros or other
> mecanism for to avoid the efect of this flag in the compilation of my
> share library,thanks in advance.

I do what you are trying to do (using the -fvisibility=hidden flag), all the
time.  I've actually got that "baked" into gcc, by using a mygcc shell
script which specifies that flag and enables most warnings and ludicrously
noisy levels (I wish there was a -Wall-all-all to enabled all toggle
warnings).

It's not too hard, but does require you to touch up your code.

I hope the example below is sufficient to help you understand.  I'm
combining it with the PImpl-via-inheritance, to make the example a little
more than trivial (but not by much).  Not using a namespace, in real world
C++ code you probably should use a namespace here.

Let's say I have these source code files:
FooExport.h -- the magic you are looking for
FooPublic.h -- my public API
FooPrivate.h -- my internals, not shipped with the DLL
Foo.cpp -- the source, also not shipped

------ FooExport.h ------
#ifndef FooExport_h
#define FooExport_h
#define EXPORT __attribute__((visibility("default")))
#define CLASS_EXPORT __attribute__((visibility("default")))
#endif
-------------------------

EXPORT and CLASS_EXPORT are both defined, to make it easier to work with
other platforms (e.g., Microsoft Windows) which use a different convention.

The CLASS_EXPORT is used to export the RTTI typeinfo, which is vital for
dynamic_cast, catching exceptions.

The EXPORT is used to export free standing functions, global variables,
methods (object functions), and class (static) functions.


------ FooPublic.h ------
#ifndef FooPublic_h
#define FooPublic_h
#include "FooExport.h"
#include <memory>

class CLASS_EXPORT Foo
{
public:
  EXPORT virtual ~Foo();
  EXPORT void Something();

private:
  virtual void DoSomething() = 0;
};

EXPORT std::auto_ptr<Foo> NewFoo();
#endif
-------------------------

The Something / DoSomething trick makes it easier to debug Something, by
setting a breakpoint on the non-virtual Something.

The destructor is virtual, otherwise the std::auto_ptr<Foo> won't properly
destruct.

The std::auto_ptr specified in the NewFoo factory function is to convey, in
code (rather than in a comment), explicit transfer of ownership (and hence
lifetime management and memory management).

Some bugs left in the Foo class:
+ the compiler provided synthetic copy-constructor was not squelched.
+ the compiler provided synthetic assignment-operator was not squelched.


------ FooPrivate.h ------
#ifndef FooPrivate_h
#define FooPrivate_h
#include "FooPublic.h"
class PrivateFoo
  :
  public Foo
{
public:
  PrivateFoo(
    int inX,
    int inY);

  virtual ~PrivateFoo();

private:
  virtual void DoSomething();

  int x;
  int y;
};
#endif
-------------------------

------ Foo.cpp ------
#include "FooPublic.h"
#include "FooPrivate.h"
#include <iostream>

std::auto_ptr<Foo> NewFoo()
{
  std::cout << "NewFoo factory says 'making the foo'" << std::endl;
  std::auto_ptr<Foo> result(new PrivateFoo(7, 100));
  return result;
}

void Foo::Something()
{
  std::cout << "Foo says 'Something'" << std::endl;
  DoSomething();
}

Foo::~Foo()
{
  std::cout << "Foo says 'bye bye'" << std::endl;
}

PrivateFoo::PrivateFoo(
  int inX,
  int inY)
  :
  x(inX),
  y(inY)
{
  std::cout << "PrivateFoo says 'hello'" << std::endl;
}

void PrivateFoo::DoSomething()
{
  std::cout << "PrivateFoo says 'DoSomething'" << std::endl;
  std::cout << "x:" << x << " y:" << y << std::endl;
}

PrivateFoo::~PrivateFoo()
{
  std::cout << "PrivateFoo says 'bye bye'" << std::endl;
}
-------------------------


CAVEAT:  I did not compile and run the above code.  Just off the cuff.
Probably has embarrassing bugs, typos, and omissions.

Sincerely,
--Eljay


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]