dlopen() not finding symbol

I used dlxxx apis so that I can load a library dinamically. As you know, there are binary (as a host) and a shared library.

In the host app, there are some symbols which should be used by the shared library. However, none of other parts of the host app uses those symbols, so I need to prevent those symbols from stripping.

// Host app
// main.cpp

extern "C"
{
#include "jpeglib.h"
}

void PreventLibjpegAPIsFromStripping(bool flag);
void InitApp();

int main()
{
InitApp();
// ...

void* handle = dlopen("test.so", RTLD_NOW);

typedef void (*DrawJpegPtr)(const char* path);
DrawJpegPtr drawJpeg = (DrawJpegPtr)dlsym(handle, "DrawJpeg");
drawJpeg("/usr/test.jpg");

dlclose(handle);
}

void InitApp()
{
// To keep the libjpeg symbols.
PreventLibjpegAPIsFromStripping(false);

// initialization code block
}

void PreventLibjpegAPIsFromStripping(bool flag)
{
struct jpeg_compress_struct cinfo;
struct jpeg_decompress_struct dcinfo;
struct jpeg_error_mgr jerr;

if(accept)
{
jpeg_std_error(&jerr);
jpeg_stdio_src(&dcinfo, 0);
jpeg_create_compress(&cinfo);
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 0, 0);
jpeg_stdio_dest(&cinfo, 0);
jpeg_start_compress(&cinfo, 0);
jpeg_destroy_compress(&cinfo);
jpeg_write_scanlines(&cinfo, 0, 1);
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
}
}

// the shared library
// test.cpp

extern "C"
{
#include "jpeglib.h"

void DrawJpeg(const char* path)
{
// some code which is drawing a jpeg with libjpeg.
// ..
}
}

And I compiled the shared library with below shell commands.

$> g++ -c -fPIC test.cpp
$> g++ -shared -o test.so test.o
$> g++ main.cpp -I./libjpeg -ldl -ljpeg -L./libjpeg

///////////////////////////

When I ran this test app, I got a undefined symbol runtime error. This error was "undefined symbol jpeg_write_scanlines". It didn't make sense at all. I checked if there was a symbol, "jpeg_write_scanlines" in the test app. There was "jpeg_write_scanlines" symbol. I really don't know what I'm missing.

Any advice about it?

Thanks in advance.
Make sure that the host application is linked with the flag -rdynamic.
I resolved this problem with linker option. There are both ways, one is to use -rdynamic(--export-dynamic). However, this way exposes all the symbols in the host app. So it'll increase its total binary size.

Another way is to use symbol list which let linker know what symbols need to be exposed or holded by the host app. In my case, I used "-Wl,-dynamic-list,symbol-list" option.

The symbol-list file contains all the symbols.

// symbol-list (my symbol list file)
{
jpeg_std_error;
jpeg_stdio_src;
jpeg_create_compress;
jpeg_set_defaults;
jpeg_set_quality;
jpeg_stdio_dest;
jpeg_start_compress;
jpeg_destroy_compress;
jpeg_write_scanlines;
jpeg_finish_compress;
jpeg_destroy_compress;
};


Last edited on
Topic archived. No new replies allowed.