你好Stack Overflow的好人,我再次回答这个问题吧!哈哈
所以我有几个文件,我试图编译和链接在一起。我创建的库是一个DLL。使用RTLD_LAZY
方法。我将该库与应用程序放在同一目录中。我很难完成这项任务。我正在尝试使用-ldl
链接它。
我的文件是:
lab3.c //Which has my main
myLibrary.c //which is my library
sdv.h //which is my header file
testDynamic.c //which is my handle file for the RTLD_LAZY
这是我到目前为止所做的,但我显然已经搞砸了......
dynamic: lab3.o myLibrary.o test
gcc -o dynamic lab3.o myLibrary.o -lm
lab3.o: lab3.c
gcc -fPIC -c -o lab3.o lab3.c -lm
myLibrary.o: myLibrary.c
gcc -fPIC -c myLibrary.c -o myLibrary.o -lm
libmyLibrary.so: myLibrary.o
gcc -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:
gcc testDynamic.c -L. -lmyLibrary -o test -ldl
export LD_LIBRARY_PATH=./
任何建议将不胜感激!提前谢谢!
答案 0 :(得分:0)
这是一个靠近你自己的makefile的例子。
生成文件:
CC=gcc
CFLAGS=-Wall -Wextra -Werror -std=gnu99
.PHONY:all mrproper clean
all:libmyLibrary.so dynamic testDynamic
dynamic:lab3.o
$(CC) $(CFLAGS) -o dynamic lab3.o -L. -lmyLibrary -lm
lab3.o:lab3.c
$(CC) $(CFLAGS) -c -o lab3.o lab3.c
myLibrary.o:myLibrary.c
$(CC) $(CFLAGS) -fPIC -c myLibrary.c -o myLibrary.o
libmyLibrary.so:myLibrary.o
$(CC) $(CFLAGS) -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:testDynamic.c
$(CC) $(CFLAGS) -o testDynamic.o -c testDynamic.c
testDynamic:testDynamic.o
$(CC) $(CFLAGS) -o testDynamic testDynamic.o -ldl
mrproper:clean
rm -f dynamic libmyLibrary.so testDynamic
clean:
rm -f lab3.o myLibrary.o testDynamic.o
仅在链接时使用-lm
。只有在链接动态库时才需要-fPic
。仅在将程序与动态库链接时才需要-lmyLibrary
。因此生成testDynamic
不需要它,因为它会动态加载库,它不需要链接到它。
sdv.h:
#ifndef SDV_H
#define SDV_H
extern void sdv_print_version();
#endif
myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v1.0\n");
}
testDynamic.c:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define MY_LIB "libmyLibrary.so"
#define PRINT_VERSION "sdv_print_version"
int main()
{
void *handle = dlopen(MY_LIB, RTLD_LAZY);
if (handle == NULL)
{
fprintf(stderr, "%s\n", dlerror());
return 1;
}
void (*p_print_version)() = NULL;
p_print_version = dlsym(handle, PRINT_VERSION);
if (p_print_version == NULL)
{
printf("No version available.\n");
fprintf(stderr, "%s\n", dlerror());
}
else
{
(*p_print_version)();
}
if (dlclose(handle) != 0)
{
fprintf(stderr, "%s\n", dlerror());
}
return 0;
}
现在建设:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
gcc -Wall -Wextra -Werror -std=gnu99 -c -o lab3.o lab3.c
gcc -Wall -Wextra -Werror -std=gnu99 -o dynamic lab3.o -L. -lmyLibrary -lm
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic.o -c testDynamic.c
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic testDynamic.o -ldl
让我们保留动态库的第一个版本:
>mkdir v1.0
>mv libmylibrary.so v1.0/
现在更新myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v2.0\n");
}
再次建造:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
让我们将这个新的动态库移动到另一个目录:
>mkdir v2.0
>mv libmylibrary.so v2.0/
现在测试时没有动态库:
>export LD_LIBRARY_PATH=./
>PATH=$PATH:.
>dynamic
dynamic: error while loading shared libraries: libmyLibrary.so: cannot open shared object file: No such file or directory
>testDynamic
libmyLibrary.so: cannot open shared object file: No such file or directory
有什么区别?在“testDynamic.c”中,我们可以,而不是显示消息错误,做一个不需要“libmyLibrary.so”的替代算法。
现在检查我们可以使用“libmyLibrary.so”:
>cd v1.0
>../dynamic
v1.0
>../testDynamic
v1.0
>cd ../v2.0
>../dynamic
v2.0
>../testDynamic
v2.0