当前位置:   article > 正文

C++学习笔记(二)——extern “C“ 用法详解_c++ extern c

c++ extern c

目录

extern "C"是什么?

使用场景:

静态库的创建

C++程序调用C写的静态库

C程序调用C++写的静态库

 


extern "C"是什么?

前面一章节简单的介绍了extern "C"的基本概念就是有时候在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern "C",意思是告诉编译器,将该函数按照C语言规则来编译。

这一章将进行详细介绍其用法,为了更好地了解,下面将举个OJ题实例:

使用场景:

题目: 有效括号

解这道题需要我们自己写个栈,但是这里为了讲解extern "C"的用法,将把栈一系列操作写好编译到静态库中然后进行调用:

  1. bool isValid(char* s) {
  2. ST st;
  3. StackInit(&st);
  4. int i = 0;
  5. while (s[i])
  6. {
  7. //左括号就插入
  8. if (s[i] == '(')
  9. {
  10. StackPush(&st, ')');
  11. }
  12. else if (s[i] == '{')
  13. {
  14. StackPush(&st, '}');
  15. }
  16. else if (s[i] == '[')
  17. {
  18. StackPush(&st, ']');
  19. }
  20. else
  21. {
  22. //if (st.empty())//栈里为空,且现在为右括号就直接返回false
  23. // return false;
  24. if (!StackEmpty(&st) && StackTop(&st) == s[i])
  25. {
  26. StackPop(&st);
  27. }
  28. else
  29. {
  30. StackDestroy(&st);
  31. return false;
  32. }
  33. }
  34. i++;
  35. }
  36. if (StackEmpty(&st))
  37. {
  38. StackDestroy(&st);
  39. return true;
  40. }
  41. else
  42. {
  43. StackDestroy(&st);
  44. return false;
  45. }
  46. }
  47. int main()
  48. {
  49. char str1[] = "{[]}";
  50. char str2[] = "([)]";
  51. printf("%d\n", isValid(str1));
  52. printf("%d\n", isValid(str2));
  53. return 0;
  54. }

静态库的创建

静态库,目前我还不太清楚,后面会在linux中跟大家一起探讨,现在咱们就理解成别人写好给你用的,被编译好的程序.

先创建一个空项目,把之前写的栈放进去,然后打开项目属性,把.exe属性改为静态库(lib)属性即可:

编译后运行,静态库就完成了。

C程序调用C写的静态库,显然没有任何阻碍可以正常操作,同理C++程序调用C++写的静态库也不会有问题,这里就不带大家一起操作了。下面我将讲解C++调用C写的静态库 和C调用C++写的静态库的操作。

C++程序调用C写的静态库

调用库之前我们要做如下操作:

第一步:

第二步:

 然后下面就可以操作起来了.

C++调用C写的静态库

首先需要包含头文件(创建栈静态库的路径)

#include "../stack/stack/stack.h"

.表示当前目录

..表示上一层目录

 然后我们来运行一下:

这里出现了链接错误,通过前一章函数重载的学习我们很快会发现问题的所在:C++修饰函数名的方法与C修饰函数名方法不一样,导致在静态库找不到这些函数,因此我们引出了:extern "C"

 这段代码的意思是:告诉编译器在调用这个静态库时,调用函数使用C的风格去调用(即调用函数时不使用函数名修饰规则)

这样我们就可以正常运行了:

C程序调用C++写的静态库

首先我们把先前C++的项目后缀改成 .c,把静态库的c文件改成cpp,我们试着反着来调用,会发生什么。 

 很显然C程序无法调用C++静态库中函数名被修饰的函数

所以我们需要在C++静态库中使用extern "C",因为c程序中无法识别extern "c"

我们这里介绍两种方法来修改:

第一种:

  1. #ifdef __cplusplus
  2. extern "C"
  3. {
  4. #endif
  5. //初始化栈
  6. void StackInit(Stack* ps);
  7. //销毁栈
  8. void StackDestroy(Stack* ps);
  9. //压栈
  10. void StackPush(Stack* ps, STDatatype x);
  11. //出栈
  12. void StackPop(Stack* ps);
  13. //取出栈顶元素
  14. STDatatype StackTop(Stack* ps);
  15. //栈的大小
  16. int StackSize(Stack* ps);
  17. //判断栈是否为空
  18. bool StackEmpty(Stack* ps);
  19. #ifdef __cplusplus
  20. }
  21. #endif

第二种:

  1. #ifdef __cplusplus
  2. #define EXTERN_C extern "C"
  3. #else
  4. #define EXTERN_C
  5. #endif
  6. //初始化栈
  7. EXTERN_C void StackInit(Stack* ps);
  8. //销毁栈
  9. EXTERN_C void StackDestroy(Stack* ps);
  10. //压栈
  11. EXTERN_C void StackPush(Stack* ps, STDatatype x);
  12. //出栈
  13. EXTERN_C void StackPop(Stack* ps);
  14. //取出栈顶元素
  15. EXTERN_C STDatatype StackTop(Stack* ps);
  16. //栈的大小
  17. EXTERN_C int StackSize(Stack* ps);
  18. //判断栈是否为空
  19. EXTERN_C bool StackEmpty(Stack* ps);

 现在就可以正常运行了:

 以上是extern "C" 的详细操作,有不足的地方或者对代码有更好的见解,欢迎评论区留言共同商讨,共同进步!! 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/264331
推荐阅读
相关标签
  

闽ICP备14008679号