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: Alastair Houghton <email@hidden>
- Date: Mon, 10 Dec 2007 14:41:44 +0000
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
_______________________________________________
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