C++调用C语言写成的动态链接库

December 09, 2023
测试
测试
测试
测试
3 分钟阅读

1.C++和C生成的符号信息不一样

C++在语法上是兼容C的,但是这不代表使用C语言不做任何处理直接写成的动态链接库就可以被C++给调用。由于C++引入了函数重载的机制,而这个机制的实现是在编译器层面的。编译器在“生成”函数符号信息时,不能仅仅通过函数名,因为重载函数的函数名都是一样的,所以它还要根据函数参数,命名空间等信息来确定唯一的函数签名;而C语言没有函数重载机制,C语言编译器在处理的时候通过函数名就可以唯一确定一个函数。这就导致C语言和C++语言生成的函数签名是不同的,故不能不做任何处理直接调用。下面我们来看一下C和C++编译同样一段代码为动态链接库以后的,它们的函数符号信息有什么不一样。

#include<stdio.h>

void Print_HelloWorld()
{
    printf("Hello World!\n");
}

保存这段代码为两份,分别是helloworld_c.c和helloworld_cpp.cpp。下面编译它们为动态链接库。

下面使用nm命令来查看生成的函数符号信息。

可以看到gcc和g++生成的函数符号信息是不同的,因此,不做任何处理肯定是不能直接调用的。这里使用nm命令可以查看符号信息是因为我们没有给这两个动态链接库进行“瘦身”。在实际开发和应用中,你的动态链接库应该先进行“瘦身”。命令如下:

进行“瘦身”以后,符号信息等就被处理掉了,动态链接库的体积也会相应的减少。我们就无法通过nm查看了,如下所示。

2.如何使C++能调用C动态链接库

C语言提供了extern "C"来使得C++能够调用C。例子如下所示:

helloworld_c.h文件

#ifndef HELLOWORLD_C_H
#define HELLOWORLD_C_H

#include <stdio.h>

#ifdef __cplusplus          //使用__cplusplus宏配合extern "C"来告诉C++链接器,这是一个C接口。

extern "C"{
#endif

void Print_HelloWorld();

#ifdef __cplusplus
}
#endif

#endif //HELLOWORLD_C_H

helloworld_c.c文件

#include"helloworld_c.h"

void Print_HelloWorld()
{
    printf("Hello World!\n");
}

main.cpp文件

#include"helloworld_c.h"

int main()
{
    Print_HelloWorld();

    return 0;
}

首先,我们把helloworld_c.c文件编译为动态链接库,名为lib_helloworld_c.so

然后,把这个动态链接库拷贝一份到/usr/lib下面即可。

最后,编译main.cpp文件。编译的时候需要链接动态链接库,编译命令如下:

g++ main.cpp -o main -L. -l_helloworld_c

这样就会生成一个名为main的可执行文件。./main执行之后就会看到输出如下:

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多