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

目录
  • 一、c++项目如何调用c的库(以静态库为例)
    • 1.将栈的源文件和头文件拷贝一份到Stack_c.lib这个项目的路径下
    • 2.打包成静态库
    • 3.建立一个c++项目(TestStacklib) 引入c项目中的头文件
    • 4.设置附加库和附属关系
  • 二、c项目如何调用c++的库(静态库为例)
    • 1.建立c++项目(Stack_cpp) 并且将栈的源文件和头文件包含在该目录 将其打包为cpp的静态库
    • 2.建立c项目
    • 3.包含静态库的头文件
    • 4 .添加打包的cpp动态库到附加库目录 设置依赖项
  • 总结

本文主要介绍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目录的路径复制到附加库目录中

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

到此准备工作就完成了 接下来有两种方法可以实现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 不太好)

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

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

格式:

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++静态库间相互调用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于使用rust调用c++静态库并编译nodejs包的问题

    目录 一.创建项目 二.Cargo.toml 三.package.json 四.代码分析 在项目上经常要用到身份证阅读器.护照阅读仪.指纹仪等各种品牌硬件,假如每套系统的都做集成开发那代码的维护成本将变得很高,为此采用rust来调用厂家提供的sdk c++开发包并封装成nodejs包,用fastify来开发成web api独立的服务形式.这样我们开发系统时只需调用web接口即可,跨平台又可共用,方便快捷,话不多说来看代码如何实现. 一.创建项目 安装rust后,打开vs新建一个工程目录,我们通过

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

    目录 一.c++项目如何调用c的库(以静态库为例) 1.将栈的源文件和头文件拷贝一份到Stack_c.lib这个项目的路径下 2.打包成静态库 3.建立一个c++项目(TestStacklib) 引入c项目中的头文件 4.设置附加库和附属关系 二.c项目如何调用c++的库(静态库为例) 1.建立c++项目(Stack_cpp) 并且将栈的源文件和头文件包含在该目录 将其打包为cpp的静态库 2.建立c项目 3.包含静态库的头文件 4 .添加打包的cpp动态库到附加库目录 设置依赖项 总结 本文主

  • Android Activity之间相互调用与传递参数的原理与用法分析

    本文实例讲述了Android Activity之间的相互调用与传递参数.分享给大家供大家参考,具体如下: Activity之间是如何调用的 在javaWeb程序中,jsp与jsp之间的调用是通过重定向完成的,而在Android中,Activity与Activity之间的切换是通过Intent来完成的. 所谓Intent,它是Android中非常重要的内置组件,他可以理解为"我要干一件什么事情".在Android中有3大组件:Activity,Service.Broadcast,他们之间

  • C与C++之间相互调用实例方法讲解

    1.导出C函数以用于C或C++的项目 如果使用C语言编写的DLL,希望从中导出函数给C或C++的模块访问,则应使用 __cplusplus 预处理器宏确定正在编译的语言.如果是从C++语言模块使用,则用C链接声明这些函数.如果使用此技术并为DLL提供头文件,则这些函数可以原封不动地由C和C++模块使用. 以下代码演示可由 C 和 C++ 客户端应用程序使用的头文件: 复制代码 代码如下: // MyCFuncs.h#ifdef __cplusplusextern "C" {  // o

  • 关于Iframe父页面与子页面之间的相互调用

    iframe元素就是文档中的文档. window对象: 浏览器会在其打开一个HTML文档时创建一个对应的window对象.但是,如果一个文档定义了一个或者多个框架(即:包含一个或者多个frame或者iframe标签),浏览器就会为原始文档创建一个window对象,再为每个iframe创建额外的window对象,这些额外的window对象是原始窗口的子窗口. contentWindow: 是指指定的iframe或者iframe所在的window对象 Demo1 父页面fu.html: <!DOCT

  • 如何实现springboot中controller之间的相互调用

    springboot controller之间相互调用 SpringBoot之间内部调用 @Autowired private RestTemplate restTemplate ;//自动装配restTemplate -------------------返回json字符串类型---------------------------------- @RequestMapping("/selectHospatal") @ResponseBody public String selectH

  • Python与C/C++的相互调用案例

    一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可. (1)C语言文件:pycall.c /***gcc -o libpycall.so -shared -fPIC pycall.c*/ #include <stdio.h> #include <stdlib.h> int f

  • xcode 4 制作静态库图文详解

    最近在做Apple的IOS开发,有开发静态库的需求,本身IOS的开发,只允许静态库或者Framework.在Xcode上没有找到允许编译,如同Android上的*.so和Win32上的dll这样的说法.不过Framework这样的框架,估计也是类似动态库的实现,不过没有具体研究过,后续继续深入研究. 我这个文档的静态库的开发是基于Xcode4.2和iOS SDK5.0编写的.Xcode4跟之前的Xcode3还是有不少的差别的.下面就简单写一个静态库和一个调用静态库的例子.静态库的编写:1.静态库

  • Android编程使用WebView实现与Javascript交互的方法【相互调用参数、传值】

    本文实例讲述了Android编程使用WebView实现与Javascript交互的方法.分享给大家供大家参考,具体如下: Android中可以使用WebView加载网页,同时Android端的Java代码可以与网页上的JavaScript代码之间相互调用. 效果图: (一)Android部分: 布局代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&qu

  • Python父目录、子目录的相互调用方法

    最近在使用Python的过程中经常遇到找不到该模块的问题.其中一个就是父目录子目录之间相互调用的情况.下面简单总结下. 我们在F:\Code文件夹下面创建一个test文件夹 而test文件夹里面如下 包含两个子目录 a.py def showdata(): print("this is a") def plus(): a=1 b=2 print(a+b) b.py def show(): print("this is b") 从父目路test.py调用a和b fro

  • vue 需求 data中的数据之间的调用操作

    我遇到过这种情况 就是在我的data中 会有数据调用data中的其他数据 如图 我的alertInfoType需要拿到screeningCondition中type的值 用过vue的都知道 我是不能写成alertInfoType:this.screeningCondition.type这种的 原理是什么?忘记了 知道了可以评论说下 所以 我们可以这样写 在mounted中直接赋值就可以了! 不知道你们有么有遇到过这种情况 反正我是遇到了两次了 第一次忘记怎么处理的了 ...... over 希望

随机推荐