如何在windows下使用开源库?

一、前言

大家好,我是ZhengN。

最近工作中需要把项目嵌入式Linux平台代码移到Windows上做仿真模拟,需要解决三个问题:

搭建工程上一篇已经分享了:实用 | 使用Cmake快速生成visual studio工程

这篇我们来看看怎么在Windows上编译动态库。我们的项目中用到了几个开源库,下面通过实例来演示怎么编译得到相应的动态库。

二、静态、动态链接?

在实例演示之前,有必要先简单了解一下静态、动态链接,因为有些初学的小伙伴可能不太了解。

编译链接过程如:

如何在windows下使用开源库?


1、什么是静态链接?

静态链接是由链接器在链接时将库的内容加入到可执行程序中的做法。

链接器是一个独立程序,将一个或多个库或目标文件(先前由编译器或汇编器生成)链接到一块生成可执行程序。

这里的库指的是静态链接库,Windows下以.lib为后缀,Linux下以.a为后缀。

2、什么是动态链接?

动态链接(Dynamic Linking),把链接这个过程推迟到了运行时再进行,在可执行文件装载时或运行时,由操作系统的装载程序加载库。

这里的库指的是动态链接库,Windows下以.dll为后缀,Linux下以.so为后缀。

需要注意的是,在Windows下的动态库也会提供两个文件:.lib文件与.dll文件。但这里的.lib文件叫做导入库,是由.dll文件生成的。

导入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接导入库,DLL中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载DLL,访问DLL中导出的函数。

3、静态链接与动态链接的优缺点?

(1)静态链接的优缺点:

优点:

缺点:

(2)动态链接的优缺点:

优点:

缺点:

4、动态链接动态链接优缺点类比

我们可以把静态链接与动态链接做一个这样子的比喻:把链接过程看做我们平时学习时做笔记的过程

我们平时学习时准备一本笔记本专门记录我们的学习笔记,比如在某本书的某一页上看到一个很好很有用的知识,这时候我们有两种方法记录在我们的笔记本上。

一种是直接把那一页的内容全部抄写一遍到笔记本上(静态链接);另一种是我们在笔记本上做个简单的记录(动态链接),比如写上:xxx知识点在《xxx》的xxx页。

从这两种方法中我们可以很清楚地知道两种方式的特点。第一种方式的优点就是我们在复习的时候就很方便,不用翻阅其它书籍了,但是缺点也很明显,就是占用笔记本的空间很多,这种方法很快就把我们的笔记本给写满了。

第二种方式的优点就是很省空间,缺点就是每当我们复习的时候,手头上必须备着相关的参考书籍,比如我们去教室复习的时候,就得背着一大摞书去复习,这样我们复习的效率可能就没有那么高了。

这对应到我们的动态链接与静态链接上是不是就很好理解了。

三、编译开源库

下面以实例来演示Windows在下编译开源库,以编译开源库nanomsg为例。

关于nanomsg的文章:

实用 | 一个高性能通信库的简单使用分享

nanomsg下载链接:

https://github.com/gaobaoru/nanomsg/

1、编译nanomsg的动态库

一般开源库都会用CMakeLists.txt来管理工程,找到库的CMakeLists.txt文件所在路径,如:

如何在windows下使用开源库?


这个路径下面会用到。需要注意的是,这个CMakeLists.txt不一定在根目录下,有些库会专门建一个文件夹来存放CMakeLists.txt。

在nanomsg根目录新建一个文件夹存储我们编译得到的库,如nanomsg_x64_lib

如何在windows下使用开源库?


使用cmake-gui生成nanomsg的vs2019工程:

如何在windows下使用开源库?


如何在windows下使用开源库?


如何在windows下使用开源库?


如果Configure这一步顺利的话,会出现Configuring done:

如何在windows下使用开源库?


可能会出现一些警告或错误,不重要的警告我们就先不用管,如果有错误的话根据错误提示进行解决。

生成动态库还是静态库,可以进行选择:

如何在windows下使用开源库?


然后点击Generate就生成VS工程:

如何在windows下使用开源库?


这时候可以看到我们的nanomsg_x64_lib文件夹下有生成VS工程文件了:

如何在windows下使用开源库?


可以双击打开nanomsg.sln,也可以点击cmake-gui的Open Project打开工程:

如何在windows下使用开源库?


nanomsg解决方案中有58个项目,因为包含有一些例子之类的。我们只用到nanomsg项目,把这个项目设置为启动项目:

如何在windows下使用开源库?


按快捷键Ctrl+B生成nanomsg:

如何在windows下使用开源库?


如何在windows下使用开源库?


没问题的话就可以看到编译生成nanomsg.lib与nanomsg.dll了。

2、动态库使用验证

上一步编译生成了nanomsg动态库,这一节我们来一起使用验证一下。

验证代码我们拿实用 | 一个高性能通信库的简单使用分享 这篇文章的代码来修改。

nanomsg可用于多线程、多进程、多机通信。nanomsg是一个socket library,所以其应用接口与标准的socket接口差不多,只是多了前缀nn_,如nn_socket、nn_close、nn_send、nn_recv等。关于socket可查阅往期笔记:

TCP、UDP通信总结

下面演示进程间通信的client-server的例子,以下测试代码主要实现的是client-server进行收发测试。

nanomsg_server.c:

#include 
#include 
#include 
#include "pair.h"
#include "bus.h"
#include "nn.h"

#pragma comment (lib,"nanomsg.lib")  // 链接导入库nanomsg.lib

#define BUF_LEN  100

char *url = "tcp://127.0.0.1:2021";
 
int main(void)
{
    int server_sock = 0;
    char buf[BUF_LEN] = {0};
    
    if (server_sock = nn_socket (AF_SP, NN_PAIR) < 0)
    {
        printf("create server socket failed!
");
        return -1;
    }
    
    if (nn_bind(server_sock, url) < 0) 
    {
        printf("bind server sock failed!r
");
        nn_close(server_sock);
        return -1;
    }
    printf("server init success!
");
    while (1)
    {
        if (nn_recv(server_sock, buf, sizeof(buf), 0) < 0) 
        {
            printf("recv failed!
");
            nn_close(server_sock);
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("recieve client msg: %sr
", buf);
            if (nn_send(server_sock, buf, sizeof(buf), 0) < 0)
            {
                printf("send failed!r
");
                nn_close(server_sock);
                exit(EXIT_FAILURE);
            }
        }
    }
    nn_close(server_sock);
    
    return 0;
}

在VS中,引入导入库有两种方式,一种方式是在工程属性设置中设置;另一种方式是使用#pragma comment的方式引入。这里我们用的是第二种。我们的nanomsg_server工程下有:

如何在windows下使用开源库?


编译没问题,运行会出错:

如何在windows下使用开源库?


找不到nanomsg动态库。我们把nanomsg.dll放入到与.exe文件同目录即可:

如何在windows下使用开源库?


再次运行没问题:

如何在windows下使用开源库?


nanomsg_client.c:

#include 
#include 
#include 
#include "pair.h"
#include "bus.h"
#include "nn.h"

#pragma comment (lib,"nanomsg.lib") // 链接导入库nanomsg.lib

#define BUF_LEN  100
 
char *url = "tcp://127.0.0.1:2021";
 
int main(void)
{
    int client_sock = 0;
    char buf[BUF_LEN] = {0};
    
    if (client_sock = nn_socket (AF_SP, NN_PAIR) < 0)
    {
        printf("create server socket failed!
");
        return -1;
    }
    
    if (nn_connect(client_sock, url) < 0) 
    {
        printf("connect server sock failed!r
");
        nn_close(client_sock);
        return -1;
    }
    printf("client init success!
");
    while (1)
    {
        scanf_s("%s", buf, BUF_LEN);
        if (nn_send(client_sock, buf, sizeof(buf), 0) < 0)
        {
            printf("send failed!r
");
            nn_close(client_sock);
        }
        memset(buf, 0, BUF_LEN);   

        if (nn_recv(client_sock, buf, sizeof(buf), 0) > 0) 
        {
            printf("recieve server msg: %sr
", buf);
        }
        memset(buf, 0, BUF_LEN);   
    }
    nn_close(client_sock);
    
    return 0;
}

nanomsg_client代码及注意事项与nanomsg_server类似,这里不再说明。

运行验证:

如何在windows下使用开源库?


以上就是本次的分享,如有错误,欢迎指出,谢谢!

原创不易,码字不易,如果文章对你有帮助,麻烦帮忙点赞/在看/转发,谢谢!

四、资源下载

本篇笔记用到的资源、包括代码例子工程可以分享给大家,可在私信回复关键词:制作动态库,我看到的话会及时发给大家。


猜你喜欢:

嵌入式必备之Git的使用

分享一些可以快速入门的嵌入式教程

C语言、嵌入式中几个非常实用的宏技巧


1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。私信回复1024,即可免费获取!



展开阅读全文

页面更新:2024-04-02

标签:优缺点   后缀   静态   嵌入式   函数   过程   代码   方式   链接   笔记本   文件   程序   项目   动态   工程   科技

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top