LINUX.ORG.RU

undefined symbol: test


0

0

Вообщем есть необходимость подключать к программе модули (плагины).
Посмотрел доку на opennet'е и сделал значится следующий модуль, 
libpbmysq.so:

void test()
{
}

собрал его как надо, с -shared и -fPIC. Появилась требуемая сошка.
Сама же сошка подключается к главной проге через следующий метод 
класса:

//Struct of db module
struct moddb{
	void (*test)();
	void *handle;
	char *modpath;
};

bool PBModDB::registerModDB(char *dbtype)
{
	char *error, *cwd;
	
	cwd = new char[PATH_LENGTH];
	getcwd(cwd,PATH_LENGTH);
	strcat(cwd,"/");
	db->modpath = new char[strlen(cwd)+strlen(PB_MOD_DB_PREFIX)+strlen(dbtype)+strlen(".so")
];
	db->modpath = strcpy(db->modpath,cwd);
	db->modpath = strcat(db->modpath,PB_MOD_DB_PREFIX);
	db->modpath = strcat(db->modpath,dbtype);
	db->modpath = strcat(db->modpath,".so");
	delete cwd;

	if(open(db->modpath,O_RDONLY) < 0){
		PBWriteToLog("Can't open module for current database type\n");
		return false;
	}
	db->handle = dlopen(db->modpath, RTLD_LAZY);
	if (!db->handle) {
		fprintf (stderr, "%s\n", dlerror());
		return false;
	}
	*(void **) (&db->test) = dlsym(db->handle, "test");
	cout << "PREPARE FUNC!!\n";
	if ((error = dlerror()) != NULL)  {
		fprintf (stderr, "%s\n", error);
		cout << "ERROR2!!\n";
		return false;
	}
	db->test();

	return true;
}

В db->modpath лежит путь к либе, он на 100000 процентов верен. Но вот 
при запуске проги, при получении адреса функции возникает такое:

PREPARE FUNC!!
/Путь_к_проекту/debug/src/pbmodb/.libs/libpbmysql.so: undefined symbol: test
ERROR2!!

Что не так, почему функция не видна?!

Всё это пишется в дженте (так сказать uptodate), гцц 3.4.5.

Заранее спасибо!!!
★★★★★

Вот что я заметил, если модуль напиасн на Ц то всё работает, а если 
использовать Ц++ то ничего не пашет и появляется мессага про
андефайн символ. Что делать?! Как собрать Ц++ модуль?!

$ cat mod.c
#include <sys/mman.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>

void test()
{
printf("TEST\n");
}
$ gcc -fPIC -c mod.c
$ gcc -shared -o mod.so mod.o
$ ./loader mod.so
TEST
$ cat mod.cpp
#include <iostream>
#include <sys/mman.h>
#include <cstdlib>
#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>

using namespace std;

void test()
{
cout << "TEST()\n";
}
$ gcc -fPIC -c mod.cpp
$ gcc -shared -o mod.so mod.o
$ ./loader mod.so
/home/cyclon/Temp/mod.so: undefined symbol: test

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

А вот сам loader.cpp:

$ cat loader.cpp
  #include <unistd.h>
  #include <string.h>
  #include <errno.h>
  #include <dlfcn.h>

  #include <unistd.h>
  #include <string.h>
  #include <errno.h>
  #include <dlfcn.h>
  #include <iostream>

  #define PATH_LENGTH 256

  using namespace std;

  int main(int argc, char * argv[])
  {
      char path[PATH_LENGTH], * msg = NULL;
      void (*my_entry)();
      void * module;
    char *error;

      /* сборка имени модуля и полного пути к нему в одну строку */
      getcwd(path, PATH_LENGTH);
      strcat(path, "/");
      strcat(path, argv[1]);

      /* загрузка модуля и разрешение имен перед возвратом из dlopen */
      module = dlopen(path, RTLD_NOW);
      if(!module) {
          msg = dlerror();
          if(msg != NULL) {
              dlclose(module);
                return 1;
          }
      }

      /* попытка получить адрес функции "test" */
      *(void **) (&my_entry) = dlsym(module, "test");
        if ((error = dlerror()) != NULL)  {
        cout << error << "\n";
        dlclose(module);
        return 1;
        }

      my_entry();

      /* close module */
      if(dlclose(module)) {
            return 1;
      }

      return 0;
  }

Пардон за форматирование, ибо содрал код из примера и подгонал под себя.

cyclon ★★★★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

помогло, вот только не понятно одно, вроде так уже делал, но срабатывало, ну да ладно, всё равно сенкс :)

cyclon ★★★★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

точнее в файле mod.cpp

в mod.c такое делать ненадо

cvv ★★★★★
()
Ответ на: комментарий от cyclon

То-то. И вообще во всех Си-библиотеках надо так писать, ибо C++ приписывает к именам переменных некоторые данные о типе, когда вычисляет название символа, а Си - нет.

Spectrum
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.