C程序如何调用C++库?C++程序如何调用C库?(visual studio)

C++程序调用C库

假设现在有一个C文件,里面写了栈的实现以及相关操作,首先如何将一个C文件封装成库?

在这里插入图片描述
对项目名右键,找到属性在这里插入图片描述
在这里插入图片描述
找到配置属性->常规->配置类型->改成静态库,如何重新编译文件在这里插入图片描述
生成->重新生成解决方案,最后会生成一个.lib文件
在这里插入图片描述

在该项目的Debug文件下能找到一个.lib文件
在这里插入图片描述

至此一个C库生成完成。

然后写一段C++程序,里面要用到栈的相关操作,也就是要引用刚刚创建的C库。首先包含头文件,包含刚刚写的项目中的一个头文件(当然这是自己写的,写c文件时,h文件中是c文件相关函数的声明以及标准库中头文件的引用)。这里头文件的引用就是一个相对路径,…\表示该文件的上一个目录
在这里插入图片描述
当前目录
在这里插入图片描述
上一级目录
在这里插入图片描述
在再上一级目录中找到刚刚写的Stack_c文件

在这里插入图片描述
该文件路径的同名文件
在这里插入图片描述
里面有要包含的h文件
在这里插入图片描述
在这里插入图片描述
最后的引用路径。引用完头文件还需要配置,右键文件名,属性
在这里插入图片描述
配置属性,链接器,输入,找到附加依赖项,把要包含的库文件写到里面,文件名最后用分号分隔
在这里插入图片描述

在这里插入图片描述
然后找到常规的添加库目录,将刚刚生成的库文件路径写到里面,库文件路径可以在重新生成解决方案后下面的输出找到,但路径只要写到Debug在这里插入图片描述
在这里插入图片描述

应用,确定。

但由于C和C++的符号表中函数修饰规则不同,C++的程序找不到一个用C写的函数,但是C++兼容C,所以在头文件包含时加上extern “C”,告诉编译器用C的规则去引用该头文件。
在这里插入图片描述
至此,配置完成。

代码测试

// Stack的源文件,Stack.c
#include "Stack.h"

void StackInit(Stack* st)
{
	assert(st);
	st->data = NULL;
	st->top = 0;
	st->capacity = 0;
}

void StackDestory(Stack* st)
{
	assert(st);

	free(st->data);
	st->data = NULL;
	st->capacity = 0;
	st->top = 0;
}

void StackPush(Stack* st, STDataType x)
{
	assert(st);

	if (st->top == st->capacity)
	{
		//扩容,如果之前的容量是0,新的容量是4,不是0,新的容量是原来的两倍
		int newcapacity = (st->capacity == 0) ? 4 : (st->capacity * 2);
		st->capacity = newcapacity;
		st->data = (STDataType*)realloc(st->data, sizeof(STDataType) * newcapacity);
	}

	st->data[st->top] = x;
	st->top++;
}

void StackPop(Stack* st)
{
	assert(st);
	assert(st->top > 0);//top等于0,栈为空,不能删除
	st->top--;
}

bool StackEmpty(Stack* st)
{
	assert(st);

	return (st->top == 0);
}

STDataType StackTop(Stack* st)
{
	assert(st);
	assert(st->top > 0);

	return st->data[st->top - 1];
}
// Stack的头文件声明,Stack.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>

typedef int STDataType;

typedef struct Stack
{
	STDataType* data;
	int top;
	int capacity;
}Stack;


void StackInit(Stack* st);
void StackDestory(Stack* st);
void StackPush(Stack* st, STDataType x);
void StackPop(Stack* st);
bool StackEmpty(Stack* st);
STDataType StackTop(Stack* st);

Stack.h和Stack.c是一个项目中的,分别对应栈的函数声明与函数定义,打包库时需要一起进行编译

// 测试源文件test.cpp
extern "C"
{
	#include "../../Stack_C/Stack_C/Stack.h"
}
#include <iostream>

int main()
{
	Stack st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	std::cout << StackTop(&st) << std::endl;
	StackDestory(&st);
	return 0;
}

(测试程序很简单,创建并初始化一个栈,将1和2入栈,打印栈顶元素,最后销毁栈,其中与栈相关的函数是以C语言的规则打包的库)如果只是包含了Stack的头文件,编译用来测试的源文件,编译器会报链接错误,即虽然有函数的声明,编译器知道这些函数,但是在链接时编译器无法找到这些函数的定义
在这里插入图片描述
我们已经将这些函数打包成一个库,所以现在要做的的就是告诉编译器这个库的地址与名字,具体的配置过程刚才已经说了,配置库的地址与名字,并在引用头文件时加上extern “C”,让编译器以C语言的规则调用库中的函数,此时重新运行程序在这里插入图片描述

C程序调用C++库

假设栈的实现是用C++的代码写的,那现在有一个C程序,该怎么调用这个库?两个文件的配置过程类似,这里简略带过

首先是C++文件生成静态库,过程与C文件生成C库一样在这里插入图片描述
C程序头文件的引用
在这里插入图片描述
依赖项和依赖路径的配置
在这里插入图片描述
在这里插入图片描述
需要修改的地方是:对引用的库的头文件进行条件编译。C++中有一个__cplusplus的宏,只要是C++程序就会有这个宏。由于C++是兼容C的,所以在C++程序中可以用extern “C” 的方式,告诉编译器要以C的方式去链接调用。而C程序引用这个头文件,因为条件编译,宏替换成空,extern "C"在C程序中不会出现,只会在C++程序中出现(因为C不认识extern “C”,程序会报错)。
在这里插入图片描述
还有一种用条件编译的方式,用extern “C”{},将函数的声明包含起来,如果定义了__cplusplus这个宏,在C++程序中,extern “C”{},就会放出来。C程序中这行代码则不会放出来。

所以合理的运用条件编译可以写出兼容性强的代码
在这里插入图片描述

测试代码

// Stack.h,C++库的头文件,需要使用extern "C"使程序以C的规则编译调用C++库

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>


typedef int STDataType;

typedef struct Stack
{
	STDataType* data;
	int top;
	int capacity;
}Stack;

/*#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif*/

//
//EXTERN_C void StackInit(Stack* st);
//EXTERN_C void StackDestory(Stack* st);
//EXTERN_C void StackPush(Stack* st, STDataType x);
//EXTERN_C void StackPop(Stack* st);
//EXTERN_C bool StackEmpty(Stack* st);
//EXTERN_C STDataType StackTop(Stack* st);


#ifdef __cplusplus
extern "C"
{
#endif
	void StackInit(Stack* st);
	void StackDestory(Stack* st);
	void StackPush(Stack* st, STDataType x);
	void StackPop(Stack* st);
	bool StackEmpty(Stack* st);
	STDataType StackTop(Stack* st);
#ifdef __cplusplus
}
#endif
// test.c源文件,C程序不能有extern "C"
#include "../../Stack_CPP/Stack_CPP/Stack.h"
#include <stdio.h>

int main()
{
	Stack st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	printf("%d\n", StackTop(&st));
	StackDestory(&st);
	return 0;
}

在这里插入图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用 Visual Studio 2022 调用 C 语言的步骤如下: 1. 在 Visual Studio 2022 中创建一个新的 C++ 项目。 2. 在项目中添加 C 源文件,可以通过右键单击项目,选择“添加”->“新建项”->选择“C++文件(.cpp)”->重命名为 .c 后缀来创建 C 文件。 3. 在 C 源文件编写 C 语言的代码,并在头文件中声明函数。 4. 在 C++ 代码中通过 `#include` 指令包含 C 头文件,并调用其中的函数。 5. 设置项目属性,将 C 语言的路径添加到项目的链接器选项中,以便在编译时链接。 6. 编译并运行程序。 下面是一个示例代码,演示了如何在 Visual Studio 2022 中调用 C 语言: 在 C 源文件中(例如 `mylib.c`): ```c #include "mylib.h" int add(int x, int y) { return x + y; } ``` 在头文件中(例如 `mylib.h`): ```c #ifndef MYLIB_H #define MYLIB_H int add(int x, int y); #endif ``` 在 C++ 代码中: ```cpp #include <iostream> #include "mylib.h" int main() { int result = add(3, 4); std::cout << "The result is " << result << std::endl; return 0; } ``` 在链接器选项中添加路径步骤: 1. 右键单击项目,选择“属性”。 2. 在左侧面板中选择“链接器”。 3. 选择“常规”。 4. 在“附加目录”中添加 C 语言的路径。 5. 在“附加依赖项”中添加需要链接的,例如 `mylib.lib`。 6. 单击“确定”以保存更改。 然后编译并运行程序,就可以调用 C 语言中的函数了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值