【问题标题】:Dynamic Link Library using makefile使用 makefile 的动态链接库
【发布时间】:2016-04-08 04:25:21
【问题描述】:

您好 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=./

任何建议将不胜感激!提前致谢!

【问题讨论】:

  • 能否给出错误信息和 testDynamic 的最小来源?
  • "我创建的库是一个 DLL" "libmyLibrary.so",这在我看来有点混乱,一个 DLL 给我的印象是你在 windows 上使用的,但是 .so 文件是动态库对于 UNIX,那么您的操作系统到底是什么?
  • 我得到的错误是“加载共享库时出错:libmyLibrary.so:无法打开共享对象文件:没有这样的文件或目录@dvhh
  • @dvhh 对于我的句柄细节.....int main(){ void *handle;字符 * 错误;无效(*sphere_d)(浮动,浮动*,浮动*);浮动(*volCylinder_d)(浮动,浮动); float(*sumFloats_d)(float [], int);双(*正弦_d)(浮点数);句柄 = dlopen("libmyLibrary.so", RTLD_LAZY); if(handle == (void *)0){ fputs(dlerror(), stderr);退出(-1); } sphere_d = dlsym(句柄,“球体”);错误 = dlerror();如果(错误!= NULL){ fputs(错误,标准错误);退出(-1); } volCylinder_d = dlsym(句柄,“volCylinder”);错误 = dlerror();如果(错误!= NULL){
  • 我正在使用 Fedora!抱歉,我认为 DLL 是动态链接库的常用缩写。它是一个 .so 文件。 @jdarthenay

标签: c dynamic makefile shared-libraries gnu-make


【解决方案1】:

这里有一个接近您自己的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 2015-10-03
    • 1970-01-01
    相关资源
    最近更新 更多