c/c++静态库之间相互调用的实战案例

 更新时间:2022年08月10日 16:36:54   作者:*insist  
C++调用C的函数比较简单,直接使用extern "C" {}告诉编译器用C的规则去编译C代码就可以了,下面这篇文章主要给大家介绍了关于c/c++静态库之间相互调用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

本文主要介绍c语言写的项目如何调用c++实现的库和c++如何调用c语言实现的库

一、c++项目如何调用c的库(以静态库为例)

⛄️示例:建立一个项目Stack_c.lib,将该项目中的栈的实现的代码打包为一个静态库,再建立另一个c++的项目,并调用打包好的c实现的静态库里的栈的相关函数

1.将栈的源文件和头文件拷贝一份到Stack_c.lib这个项目的路径下

2.打包成静态库

⛄️应用好之后就点击生成解决方案 ,之后就会生成一个Stack_c.lib的静态库了 (与项目名重名了,问题不大 不要在意)

生成后我们可以点开项目的所在目录下 找到debug目录 可以看到里面多了一个Stack_c.lib的静态库文件 表示打包成功!

⛄️至此,静态库就打包好了,当然是编译器帮我们打包的,后续会更新如何自己亲手打包一个库(动静态库的知识)!

3.建立一个c++项目(TestStacklib) 引入c项目中的头文件

🎸注意:这里的引入头文件的路径可以是相对路径 其中是代表的上级目录 只需找到自己创建的动态库的头文件的路径并在新建的c++项目中包含即可

本文中的test.cpp是一段关于括号匹配的算法代码 可以用建的静态库里的栈的特性来解决

bool isValid(const char* s) {
    const char* cur = s;
    stack stack;
    StackInit(&stack);
    while (*cur != '\0')
    {
        if (*cur == '(' || *cur == '{' || *cur == '[')//如果是左括号就进栈
        {
            StackPush(&stack, *cur);
        }
        else
        {
            if (StackEmpty(&stack))//考虑到开始是右括号,那么就是栈为空,就不可能有效,直接返回FALSE
            {
                return false;
            }
            char top = StackTop(&stack);
            if (*cur == ')' && top == '(' || *cur == '}' && top == '{' || *cur == ']' && top == '[')
            {
                StackPop(&stack);
            }
            else {
                return false;
            }
        }
        cur++;
    }
    if (StackEmpty(&stack))//有可能只有一个左括号,进栈就没了,有效还有判断栈是否为空,为空才是有效括号
        return true;
    else
        return false;

}

int main()
{
    cout << isValid("{{))") << endl;
    cout << isValid("({})") << endl;
    return 0;
}

4.设置附加库和附属关系

将静态库中的debug目录的路径复制到附加库目录中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwjKkcKk-1657719900201)(C:\Users\华哥\AppData\Roaming\Typora\typora-user-images\image-20220713195455905.jpg)]

到这里附加库目录的操作就完成了 接下来就是在输入中设置依赖项了

🎸到此准备工作就完成了 接下来有两种方法可以实现c++项目调用c静态库

1.将stack_c.lib中的stack.c的后缀改成stack.cpp 即可
2.在c++项目中使用extern “C” 表示编译的时候按照c的规则编译链接(主要就是函数名修饰的规则用c的规则)因为c++是兼容c的所以c++的编译器可以这么干 反过来c是不可以兼容c++的 所以反过来是行不通的。

接着往下看:

🎸第一种方法:将Stack_c.lib中的stack.c 改名为 stack.cpp(使得其编译链接的时候是按照c++的规则,这样c++项目调c++规则生成的库就可以理所当然的调动了,但是这样的方式似乎很不着调,本来是c库,但是硬是把里面的源文件的后缀改成了cpp 不太好)

然后运行那段代码就可以成功运行了 证明调用静态库成功!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Og8Njbtu-1657719900202)(C:\Users\华哥\AppData\Roaming\Typora\typora-user-images\image-20220713201637750.jpg)]

🎸第二种:利用extern "C"改变c++项目的编译链接过程的规则由c++的规则变成c的规则,这样再调用c的静态库也就可以实现了,而且不用像第一种方法一样去改源文件的后缀(强盗行为)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYdV4ZeG-1657719900202)(C:\Users\华哥\AppData\Roaming\Typora\typora-user-images\image-20220713202155357.jpg)]

格式:

extern "C"
{
	#include"库的头文件路径"
}

之后就可以运行成功 ,表示链接成功了!就不贴图了 与上面的图一样

二、c项目如何调用c++的库(静态库为例)

还是那句话,c++兼容c 要用c项目调用c++库 那么就只能是让c++ 的库编译的时候用c的规则来,那么该咋弄呢?
还是extern “C”

1.建立c++项目(Stack_cpp) 并且将栈的源文件和头文件包含在该目录 将其打包为cpp的静态库

🎄右击项目名称 点击属性 再更改配置类型为静态库类型

🎄之后点击到项目的路径 进入debug目录 看到生成了一个Stack_cpp.lib 就说明生成打包静态库成功了!

接下来就是用extern "C"结合条件编译来使得c++项目中的代码按照c的规则来编译链接 但是c项目要包含c++静态库的头文件 那么就会在预处理的时候头文件展开 那么c项目中就也会有 extern “C” 这是不可以的 只有c++才可以识别extern “C” c是识别不了的 会报错!!!

那么如何解决 ? 条件编译这个时候就派上大用处了

🎄c++ 的文件中天然包含 __cplusplus 标识符 而c是没有的 可以以此为入口点 通过条件编译使得extern “C” 在c++项目中展开 但是在c项目中不展开 就将问题解决了

下面还有一个简化版的条件编译

//简化版
#ifdef __cplusplus
extern "C"
{
#endif

 void StackInit(stack* pst);
 void StackDestory(stack* pst);
 void StackPush(stack* pst,STDataType x);
 void StackPop(stack* pst);
 bool StackEmpty(stack* pst);
 int StackSize(stack* pst);
 STDataType StackTop(stack* pst);

#ifdef __cplusplus
}
#endif

之后就是 建立c项目 然后 建立test.c 拷贝那段关于括号匹配的代码到其中 包含静态库的头文件 添加打包的cpp动态库到附加库目录 设置依赖项 通过调用cpp静态库里的栈的函数解决 运行成功就说明c项目链接c++的静态库成功

2.建立c项目

3.包含静态库的头文件

4 .添加打包的cpp动态库到附加库目录 设置依赖项

然后就大功告成了 ,如果没有差错就可以直接运行成功了。

🎄这里需要注意的是 要记得使用静态库前完成了准备工作后一定要生成解决方案后再在来调用库!

总结

到此这篇关于c/c++静态库之间相互调用的文章就介绍到这了,更多相关c/c++静态库间相互调用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中常量与指针的示例详解

    C++中常量与指针的示例详解

    在C++学习使用过程中,每个人都不可避免地使用指针,而且都或多或少的接触过常量指针或指针常量,但是对这两个的概念还是很容易搞糊涂的,所以这篇文章主要给大家介绍了关于C++中常量与指针的相关资料,需要的朋友可以参考下
    2021-06-06
  • C++list的模拟实现

    C++list的模拟实现

    list是数据结构中的链表,在C++的STL中,有list的模板,STL中的list的结构是带头双向循环链表,当然STL中还有一个forward_list的链表,这个链表是一个带头的单链表。为了更好的理解list,我们来对其进行模拟实现。,需要的朋友可以参考
    2023-04-04
  • C++中fork函数的使用及原理

    C++中fork函数的使用及原理

    这篇文章主要介绍了C++中fork函数的使用及原理,在C++中,fork函数用于创建一个新的进程称为子进程,该进程与原始进程几乎完全相同,需要的朋友可以参考下
    2023-05-05
  • 模拟鼠标事件的实现思路及代码

    模拟鼠标事件的实现思路及代码

    这篇文章主要介绍了模拟鼠标事件的实现思路及代码,有需要的朋友可以参考一下
    2013-12-12
  • C++私有继承与EBO深入分析讲解

    C++私有继承与EBO深入分析讲解

    这篇文章主要介绍了C++私有继承,在私有继承当中,基类的公有成员和保护成员都会成为派生类的私有成员。这意味着基类的方法都会被private关键字描述,我们可以在派生类中使用它,但类对象无法直接调用,下面来看看详细内容吧
    2022-08-08
  • VC中SDK与MFC的区别浅析

    VC中SDK与MFC的区别浅析

    这篇文章主要介绍了VC中SDK与MFC的区别浅析,需要的朋友可以参考下
    2014-07-07
  • C++文件读写操作详解

    C++文件读写操作详解

    本文详细讲解了C++读写文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C++从汇编的视角审视对象的创建问题

    C++从汇编的视角审视对象的创建问题

    这篇文章主要介绍了C++从汇编的视角看对象的创建,从汇编的视角来看,调用构造器和调用 “返回对象” 的函数是一样的,从汇编的角度来看,对象就是一堆数据的排列,比如说最普通的对象就是数据成员按照声明顺序直接排列,需要的朋友可以参考下
    2022-01-01
  • C++类和对象之封装详解

    C++类和对象之封装详解

    大家好,本篇文章主要讲的是C++类和对象之封装详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Qt绘制时钟效果

    Qt绘制时钟效果

    这篇文章主要为大家详细介绍了Qt绘制时钟效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论