LINUX.ORG.RU

[C++] Не получается вызывать метод класса в share object

 


0

0

Извиняюсь за ламерский вопрос, но можно ли вызывать метод класса находящегося в so или же придётся каждую функцию выносить через extern «C»?

Есть класс помещённый в so. Есть программа которая её подключает, создаёт объект и вызывает метод.

Код:

//	mydb.h

class mydb{
	public:
		mydb(...);

		int test();
		int p;
};

typedef mydb* mydb_t(...);

/********************************/

//	mydb.cpp

#include "mydb.h"

mydb::mydb()
{
}

int mydb::test()
{
	return p;
}

extern "C" mydb *mydb_new(...)
{
	return new mysqldb(...);
}

/*************************************/

//	someapp.cpp

#include "mydb.h"

void *lib_handle;

lib_handle = dlopen("libnmydb.so.0.1", RTLD_LAZY);
if (!lib_handle) {
	printf("can't open shared\n");
	exit(1);
}

mydb_t *mydb_ = (mydb_t*) dlsym(lib_handle, "mydb_new");
if (!mydb_) {
	printf("can't load symbol\n");
	exit(1);
}

mydb *mdb = mydb_new(...);

// так ошибка при линковке
printf("%i\n",mdb->test());
// так всё работает
printf("%i\n",mdb->p);

/************************************************************/

при компиляции:

someapp.cpp:27: undefined reference to `mydb::test()'
someapp.cpp:27: undefined reference to `mydb::test()'

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

★★★★★

Последнее исправление: cyclon (всего исправлений: 1)

только через интерфейсы. Учим, как происходит линковка

или описываем методы как импортируемые/экспортируем

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

сделал так


#define EXPORT __attribute__((visibility("default")))

class EXPORT mydb{
	public:
		mydb(...);

		int test();
		int p;
};

typedef mydb* mydb_t(...);

не помогло, так же ругается

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

> не помогло, так же ругается

Естественно ругается, он ведь ищет код внутри своего собственного бинарника или прилинкованых библиотеках. Из динамической же библиотеки тело C++-функции можно вызвать через абстрактный класс, который будет переопределён в этой самой библиотеке и возвращён из неё указателем на абстрактный класс.

Dendy ★★★★★
()
Ответ на: комментарий от ahonimous
// Флаги внешнего экспорта
#if defined(NETSTREAM_LIBRARY)
#       define NETSTREAMLIBRARY_EXPORT Q_DECL_EXPORT
#else
#       define NETSTREAMLIBRARY_EXPORT Q_DECL_IMPORT
#endif

..........


class NETSTREAMLIBRARY_EXPORT _CSmartObjectEx : public QObject,
        virtual public ISmartObject
{
        Q_OBJECT
...

поищи, во что раскрываются этим макросы под gcc - мне щас не до этого

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

Добавил virtual, всё скомпилилось и работает...


#define EXPORT __attribute__((visibility(«default»)))

class EXPORT mydb{
public:
mydb(...);

virtual int test();
int p;
};

typedef mydb* mydb_t(...);

работает, но правильно ли так делать?

cyclon ★★★★★
() автор топика

man dlopen:

RTLD_GLOBAL

The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.



и еще вот здесь: http://gcc.gnu.org/faq.html#dso

gavv
()
Ответ на: комментарий от namezys

В gcc они, очевидно, раскрываются в пустоту.

Reset ★★★★★
()

Капец... Уже никто в наше время не знает даже как линкер работает...

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