目录
前言
一、C++项目调C的静态库。
二、C项目调用C++的静态库
?三、总结
前言
extern “c”的作用可以实现c语言和c++相互调用。
1.当我们写c语言代码,要调用c++代码时,可以将c++的类型配置为静态库,然后直接调用头文件。
2.当我们写c++代码,要调用c代码时,可以将c的类型配置为静态库,然后直接调用头文件。
由于c++支持函数重载,而c语言不支持函数重载,c语言和c++的函数名修饰规则有所不同,所以在链接的时候就C和C++之间无法找到对应的函数地址。所以引入extern “C”。
1.在C++项目中调用C的静态库时,告诉C++编译器,extern "C"{}里面的函数是C编译器编译的,链接的时候用C的函数名规则去找,就可以链接上。
2.在C项目中调用C++的静态库时,同样告诉C++编译器,extern "C"{}里面的函数要用C语言的修饰规则修饰。
下面我们通过代码来了演示,实验环境:VS2019。
一、C++项目调用C的静态库
我们先将写好的C程序配置成.lib的静态库:
此时该静态库的debug目录下就有.lib的静态库
然后在需要调用库的C++项目中,引入静态库:
将附加库目录的路径设置为配置好的静态库的debug路径下。
然后在链接器的输入下添加? c的lib.lib;(创建的项目名.lib)
?调用静态库的C++代码:
其中include内的 ..是跳转到上一级目录。
#include <iostream>
using namespace std;
// C++项目
// 告诉C++编译器,extern "C"{}里面的函数是C编译器编译的,链接的时候用C的函数名规则去找,就可以链接上
extern "C"
{
#include "../c的lib/Stack.h"
}
bool isValid(const char * s){
ST st = { 0 };
StackInit(&st);
while (*s)
{
if (*s == '('
|| *s == '{'
|| *s == '[')
{
StackPush(&st, *s);
++s;
}
else
{
// 遇到右括号了,但是栈里面没有数据,说明
// 前面没有左括号,不匹配,返回false
if (StackEmpty(&st))
{
StackDestroy(&st);
return false;
}
STDataType top = StackTop(&st);
StackPop(&st);
if ((*s == '}' && top != '{')
|| (*s == ']' && top != '[')
|| (*s == ')' && top != '('))
{
StackDestroy(&st);
return false;
}
else
{
++s;
}
}
}
// 如果栈不是空,说有栈中还有左括号未出
// 没有匹配,返回是false
bool ret = StackEmpty(&st);
StackDestroy(&st);
return ret;
}
int main()
{
cout << isValid("{[]}") << endl;
cout << isValid("([)]") << endl;
return 0;
}
配置静态库的c代码:
Stcak.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps);
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
Stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0; // ps->top = -1;
ps->capacity = 0;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool StackEmpty(ST* ps)
{
assert(ps);
/*if (ps->top == 0)
{
return true;
}
else
{
return false;
}*/
return ps->top == 0;
}
二、C项目调用C++的静态库
实现方法与上面类似。只需要将上面步骤的.cpp与.c文件后缀互换,然后通过条件编译,将C++静态库中的头文件的函数用extern"C"作用:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
//void StackInit(ST* ps);
//void StackDestroy(ST* ps);
//void StackPush(ST* ps, STDataType x);
//void StackPop(ST* ps);
//STDataType StackTop(ST* ps);
//int StackSize(ST* ps);
//bool StackEmpty(ST* ps);
#ifdef __cplusplus
extern "C"
{
#endif
void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);
STDataType StackTop(ST* ps);
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
#ifdef __cplusplus
}
#endif
其中__cplusplus是c++中定义好的宏。所以在c++中就会展开extern "C"{}
,而c项目调用头文件时,就没有__cplusplus这个宏就不会展开extern "C"{}。
还有另一种条件编译:
#ifdef __cplusplus
#define E extern "C"
#else
#defien E
#endif
E void StackInit(ST* ps);
E void StackDestroy(ST* ps);
E void StackPush(ST* ps, STDataType x);
E void StackPop(ST* ps);
E STDataType StackTop(ST* ps);
E int StackSize(ST* ps);
E bool StackEmpty(ST* ps);
然后在C项目中调用头文件#include "../c的lib/Stack.h",这样C项目调用时,将E替换为空 ,直接展开函数。
?三、总结
1??通过extern "C",我们可以实现C项目调C++的库,C++项目调C的库。不需要源码,只需要静态库和头文件就可以实现功能,多人协作时非常方便。
2??因为extern "C"只在C++中 起作用,所以不管是调用C的库还是C++的库,extern "C"都只在C++中处理。
不是看到希望才去坚持,而是坚持了才看到希望,敬每一位努力奋斗的你和学习编程的你。希望我的文章能对你有所帮助。欢迎👍点赞 ,📝评论,🌟关注,??收藏
|