Re: How to make a program look for dylibs other than /usr/local/lib?
Re: How to make a program look for dylibs other than /usr/local/lib?
- Subject: Re: How to make a program look for dylibs other than /usr/local/lib?
- From: "parag vibhute" <email@hidden>
- Date: Mon, 10 Dec 2007 21:05:57 +0530
Thanks Alastair for detailed information.
From ur writeup, I came to know that dlopen is intended to get address of C functions only. But the dylib whose header file I have mentioned is not under my control. It is implemented by somebody else & has given install name of dylib as /usr/lib/libopbx.lib. So from ur writeup, I came to know that there is nothing I can do in my main program & only best way is to declare those functions as Virtual by dynamic library creator. Am I right?
Thanks,
palav
On Dec 10, 2007 8:11 PM, Alastair Houghton <
email@hidden> wrote:
On 10 Dec 2007, at 07:44, parag vibhute wrote:
> class CTime
> {
> public:
> CTime();
>
> // get methods
> long year() const;
> long month() const;
> long day() const;
> long hour() const;
> long min() const;
> long sec() const;
> }
>
>
> Now please see that in above function declarations, "virtual
> keyword" is absent in function declaration.
> So in second scenario i.e. in loading library at runtime using
> dlopen etc. functions, when I tried to use the function month() I
> got error as undefined symbol.
The problem there is that the dlopen() interface was never really
intended for use with C++ objects. So, for instance, you *could* find
the address of the month() function by passing the mangled name into
dlsym(). But it would be horribly compiler specific and you'd also
need to have a way to get a CTime object in the first place.
You can solve this problem by using a *C* interface at the dylib
level. This is more portable and doesn't preclude the implementation
being in C++ if that's what you want. For instance, you might do
something like this in a C header file
// ctime_c.h
#ifdef __cplusplus
class CTime;
extern "C" {
#else
typedef struct CTime CTime;
#endif
CTime *ctime_create(void);
void ctime_destroy(CTime *ctime);
long ctime_year(CTime *ctime);
long ctime_month(CTime *ctime);
long ctime_day(CTime *ctime);
long ctime_hour(CTime *ctime);
long ctime_min(CTime *ctime);
long ctime_sec(CTime *ctime);
#ifdef __cplusplus
}
#endif
then e.g.
// ctime_c.c
#include "
CTime.h"
#include "ctime_c.h"
CTime *ctime_create(void)
{
return new CTime();
}
void ctime_destroy(CTime *ctime)
{
delete ctime;
}
long ctime_year(CTime *ctime)
{
return ctime->year();
}
and so on. (You'd put the above code into the dylib itself, not into
your main program.)
Or, you could make CTime use virtual functions (in which case you'd
still want a C API presumably to create one). Or you could make a
factory object and have a C API to create that. You'd still need all
the C++ methods to be virtual in order for the compiler to link
properly.
Another alternative might be to build everything with -flat_namespace
and then weak link against the dylib. Then when you do your dlopen(),
you can pass RTLD_GLOBAL as the option parameter. I'm not sure how
well that will work; you'd have to try it and see.
All of this, as I say, is really a consequence of you trying to use C+
+ in the interface to a library that you want to load dynamically
using dlopen(), which was never really designed to allow access to a C+
+ interface.
Anyway, if your project is intended to be distributed to others, it
may be better for you to set the install name of your dylib to
something relative to @executable_path or @loader_path, and then to
include the library in question in your bundle. That way, none of
this will be necessary; you'll just need a Copy Files build phase to
put it into your bundle, and everything will just work. Plus you
won't have to install into /usr/local---indeed, you may not even need
an installer.
Kind regards,
Alastair.
--
http://alastairs-place.net
--
There are many things in your life that will catch your eye but only a few will catch your heart....pursue those'.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden