Как мне заставить работать эту простую C-тестовую программу для загрузки модулей? - PullRequest
2 голосов
/ 08 апреля 2011

Я собирался использовать dlopen и dlsym на linux, чтобы эти два исходных файла работали:

 #include <dlfcn.h>
 #include <stdio.h>
 int main()
 {
     int *(func)(void);

     func=dlsym( dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

     printf("%d\n", *func());
     return 0;
}

и:

int func()
{
return 42;
}

но когда я скомпилирую первый,он продолжает говорить:

main.c: 9: ошибка: lvalue требуется в качестве левого операнда присваивания

edit: я попытался добавить приведение и сделать его функциейуказатель, но теперь он говорит: main.c :(. text + 0x1f): неопределенная ссылка на dlopen' main.c:(.text+0x2b): undefined reference to dlsym '

Ответы [ 3 ]

4 голосов
/ 08 апреля 2011

Ваша декларация func запутана:

int *(func)(void);

эквивалентно:

int *func(void);

так что вы просто даете компилятору прототип для func без объявления переменной; ошибка возникает из-за того, что функция не является допустимым lvalue; тем не менее, указатель на функцию является допустимым значением lvalue, поэтому вы хотите следующее:

int (*func)(void);

И тогда ваш printf должен быть таким:

printf("%d\n", func());

Вам также понадобится привести результат из dlsym, чтобы он строго соответствовал стандарту C:

func = (int (*)(void))dlsym(dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

Указатель void* может быть тихо обновлен до любого другого типа указателя, кроме указателя на функцию; gcc -pedantic, например, предупредит, что «ISO C запрещает присваивание между указателем функции и« void * »без использования приведения. У меня нет удобной копии стандартного (но кто-то здесь, конечно, есть), поэтому я не могу цитировать главу и стих, но caf верен в этом вопросе (спасибо caf).

И вы также хотите добавить в закладки cdecl.org .

0 голосов
/ 08 апреля 2011

Нет необходимости *func()

printf("%d\n", func());

будет в порядке, потому что func () вернет int, и вы попытаетесь получить разыменование (*) целого числа

посмотрите на приоритет операторов ( ссылка )

0 голосов
/ 08 апреля 2011

вы действительно не можете делать то, что пытаетесь

, но это должно быть int (func *) ()

, а printf должен быть func ()

но вы не можете назначить dlsym со всеми его параметрами в качестве указателя на функцию

подсказка .... указатель на функцию "func" это просто указатель, у него нет состояния, это просто адрес памяти

и вы не должны предоставлять функцию с именем func ....., поскольку вы создаете указатель с именем func.Вы можете сделать функцию "int test_function () {return 42;}

, затем в main go func = test_function; просто для проверки с помощью указателя функции

...