Problem calling C++ functions in Linux shared object libraries

3 messages Options
Embed this post
Permalink
Finnian

Problem calling C++ functions in Linux shared object libraries

Reply Threaded More More options
Print post
Permalink
EiffelStudio 6 (6.3.0.0 GPL Edition - linux-x86-64)
Ubuntu 8.10

Hello All,
I had been having a problem calling C++ functions in a Linux shared object library. Calling a function getRawText() in a class interface ID3_Field returns a null pointer. I couldn't understand why I was getting this as a standalone C++ program compiled against the same library was giving the correct result.

Grasping at straws I looked at the lib output folder which had 3 versions of the same library generated by an autoconf make. Don't ask me why but I decided to try explicitly linking to the static version $(ID3_LIB)/libid3.a and lo and behold my program worked. I tried explicitly linking $(ID3_LIB)/libid3.so and got the same problem again.

There is something mysterious going on with shared object libraries. Wondering if anyone has ever experienced the same.

Regards
Finnian Reilly

Emmanuel Stapf

RE: Problem calling C++ functions in Linux shared object libraries

Reply Threaded More More options
Print post
Permalink
Clearly this should not happen. Have you tried to compare the result of `ldd'
between the C++ and Eiffel executables. If the list is different for your ID3 lib,
then it will give you a clue. If it is exactly the same, make sure to replicate
the exact same C++ code in your Eiffel code as it clearly should produce the same
result.

I might also be good to pay attention to the C compiler flags used to compile the
C++ executable.

Regards,
Manu

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of finnianr
> Sent: Monday, October 26, 2009 5:48 AM
> To: [hidden email]
> Subject: [eiffel_software] Problem calling C++ functions in Linux shared
> object libraries
>
> EiffelStudio 6 (6.3.0.0 GPL Edition - linux-x86-64)
> Ubuntu 8.10
>
> Hello All,
> I had been having a problem calling C++ functions in a Linux shared
> object library. Calling a function getRawText() in a class interface
> ID3_Field returns a null pointer. I couldn't understand why I was getting
> this as a standalone C++ program compiled against the same library was
> giving the correct result.
>
> Grasping at straws I looked at the lib output folder which had 3 versions
> of the same library generated by an autoconf make. Don't ask me why but I
> decided to try explicitly linking to the static version
> $(ID3_LIB)/libid3.a and lo and behold my program worked. I tried
> explicitly linking $(ID3_LIB)/libid3.so and got the same problem again.
>
> There is something mysterious going on with shared object libraries.
> Wondering if anyone has ever experienced the same.
>
> Regards
> Finnian Reilly
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>

------------------------------------------------------------------------  
Eiffel Software
805-685-1006
http://www.eiffel.com       
Customer support: http://support.eiffel.com       
User group: http://groups.eiffel.com/join       
------------------------------------------------------------------------  
Finnian

Re: Problem calling C++ functions in Linux shared object libraries

Reply Threaded More More options
Print post
Permalink


Hello Manu
thanks for your comments on the problem. I checked the C++ example to see what library it linked against. It was libid3.la which is essentially the same as libid3.a. I changed it to link against libid3.so and sure enough I got precisely the same null pointer problem as in Eiffel.  I also tried libid3.a which ran fine.

I was suspicious that somehow the libid3.so wasn't being rebuilt as my reason for rebuilding the library in the first place was to apply a patch. Without the patch the GetRawText() routine would return null for utf8 strings. Seems too much of a coincidence. So I double checked that make clean was working correctly and it was definitely being rebuilt. This points the blame at some makefile configuration error.

The Makefile.am section for the library looks like this

    lib_LTLIBRARIES   = libid3.la

    libid3_la_SOURCES = $(id3lib_sources)

    if ID3_NEEDZLIB
    LDADD        = $(top_builddir)/zlib/src/libz.la
    endif

    libid3_la_LDFLAGS = \
      -version-info $(LT_VERSION) \
      -release $(LT_RELEASE) \
      -export-dynamic


From this autoconf produces the following make instructions:

    lib_LTLIBRARIES = libid3.la

    libid3_la_SOURCES = $(id3lib_sources)

    #LDADD = $(top_builddir)/zlib/src/libz.la

    libid3_la_LDFLAGS = \
      -version-info $(LT_VERSION) \
      -release $(LT_RELEASE) \
      -export-dynamic

    subdir = src
    mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
    CONFIG_HEADER = $(top_builddir)/config.h
    CONFIG_CLEAN_FILES =
    LTLIBRARIES = $(lib_LTLIBRARIES)

    libid3_la_LIBADD =
    am__objects_1 = c_wrapper.lo field.lo field_binary.lo field_integer.lo \
        field_string_ascii.lo field_string_unicode.lo frame.lo \
        frame_impl.lo frame_parse.lo frame_render.lo globals.lo \
        header.lo header_frame.lo header_tag.lo helpers.lo io.lo \
        io_decorators.lo io_helpers.lo misc_support.lo mp3_parse.lo \
        readers.lo spec.lo tag.lo tag_file.lo tag_find.lo tag_impl.lo \
        tag_parse.lo tag_parse_lyrics3.lo tag_parse_musicmatch.lo \
        tag_parse_v1.lo tag_render.lo utils.lo writers.lo
    am_libid3_la_OBJECTS = $(am__objects_1)
    libid3_la_OBJECTS = $(am_libid3_la_OBJECTS)
    .
    .
    .
    libid3.la: $(libid3_la_OBJECTS) $(libid3_la_DEPENDENCIES)
        $(CXXLINK) -rpath $(libdir) $(libid3_la_LDFLAGS) $(libid3_la_OBJECTS) $(libid3_la_LIBADD) $(LIBS)

Doesn't look like anything much wrong with it. I presume that autoconf produces some standard bit of code to generate the dynamic library from libid3.la although I am not sure exactly where this standard bit of code is. (I couldn't find a target named "libid3.so") Or maybe the "libid3.la:" line generates it, I don't know.

These are the libtool commands that actually get executed:

    /bin/sh ../libtool --mode=link g++  -g -O2 -Wall -Wno-unused -Wno-inline -Woverloaded-virtual -Wmissing-declarations    -o libid3.la -rpath /home/finnian/Development/Eiffel/library/Eiffel-Loop/C_library/id3lib/lib -version-info 3:0:0 -release 3.8 -export-dynamic c_wrapper.lo field.lo field_binary.lo field_integer.lo field_string_ascii.lo field_string_unicode.lo frame.lo frame_impl.lo frame_parse.lo frame_render.lo globals.lo header.lo header_frame.lo header_tag.lo helpers.lo io.lo io_decorators.lo io_helpers.lo misc_support.lo mp3_parse.lo readers.lo spec.lo tag.lo tag_file.lo tag_find.lo tag_impl.lo tag_parse.lo tag_parse_lyrics3.lo tag_parse_musicmatch.lo tag_parse_v1.lo tag_render.lo utils.lo writers.lo
    rm -fr .libs/libid3.la .libs/libid3.* .libs/libid3-3.8.*
    gcc -shared  c_wrapper.lo field.lo field_binary.lo field_integer.lo field_string_ascii.lo field_string_unicode.lo frame.lo frame_impl.lo frame_parse.lo frame_render.lo globals.lo header.lo header_frame.lo header_tag.lo helpers.lo io.lo io_decorators.lo io_helpers.lo misc_support.lo mp3_parse.lo readers.lo spec.lo tag.lo tag_file.lo tag_find.lo tag_impl.lo tag_parse.lo tag_parse_lyrics3.lo tag_parse_musicmatch.lo tag_parse_v1.lo tag_render.lo utils.lo writers.lo   -Wl,-soname -Wl,libid3-3.8.so.3 -o .libs/libid3-3.8.so.3.0.0

A typical line that compiles an individual object is

    g++ -DHAVE_CONFIG_H -I. -I. -I.. -I../include/id3 -I../include -g -O2 -Wall -Wno-unused -Wno-inline -Woverloaded-virtual -Wmissing-declarations -c tag_impl.cpp -MT tag_impl.lo -MD -MP -MF .deps/tag_impl.TPlo  -fPIC -DPIC -o .libs/tag_impl.lo


I couldn't get the autoconf sequence of tool calls to rebuild everything completely as it was designed for an older version not installed on my machine. I was afraid I might screw up my Linux install if I forced the older version to install. Anyway it shouldn't be necessary I thought because the configuration script runs fine.

Sill a mystery but I am thankful that I have at least something working.

Regards
Finnian



--- In [hidden email], "Emmanuel Stapf [ES]" <manus@...> wrote:

>
> Clearly this should not happen. Have you tried to compare the result of `ldd'
> between the C++ and Eiffel executables. If the list is different for your ID3 lib,
> then it will give you a clue. If it is exactly the same, make sure to replicate
> the exact same C++ code in your Eiffel code as it clearly should produce the same
> result.
>
> I might also be good to pay attention to the C compiler flags used to compile the
> C++ executable.
>
> Regards,
> Manu
>
> > -----Original Message-----
> > From: [hidden email]
> > [mailto:[hidden email]] On Behalf Of finnianr
> > Sent: Monday, October 26, 2009 5:48 AM
> > To: [hidden email]
> > Subject: [eiffel_software] Problem calling C++ functions in Linux shared
> > object libraries
> >
> > EiffelStudio 6 (6.3.0.0 GPL Edition - linux-x86-64)
> > Ubuntu 8.10
> >
> > Hello All,
> > I had been having a problem calling C++ functions in a Linux shared
> > object library. Calling a function getRawText() in a class interface
> > ID3_Field returns a null pointer. I couldn't understand why I was getting
> > this as a standalone C++ program compiled against the same library was
> > giving the correct result.
> >
> > Grasping at straws I looked at the lib output folder which had 3 versions
> > of the same library generated by an autoconf make. Don't ask me why but I
> > decided to try explicitly linking to the static version
> > $(ID3_LIB)/libid3.a and lo and behold my program worked. I tried
> > explicitly linking $(ID3_LIB)/libid3.so and got the same problem again.
> >
> > There is something mysterious going on with shared object libraries.
> > Wondering if anyone has ever experienced the same.
> >
> > Regards
> > Finnian Reilly
> >
> >
> >
> > ------------------------------------
> >
> > Yahoo! Groups Links
> >
> >
> >
>