文章目录
其实以前也不怎么关注这点,因为基本上自己写的库和用的第三方依赖大部分都是全 C++ 实现,基本没有 C 实现,但是写算法题的时候还是会经常用到
printf
之类的 C 函数,就很自然而然的去用了,发现编译也能通过就没怎么管。
最近自己移植一个 Unix 上的物理模拟项目,需要用到 glad 之类的 OpenGL 辅助库,突然发觉,这个项目是纯 C 实现的,如果我搬迁到 Windows 上来,Windows 下的 GLFW 和 GLAD 库都好像是 C++ 编译的吧,至少我之前用 OpenGL 的时候都是写 C++ 项目,没有 C 项目。那么这个人用纯 C 实现的例子物理约束模拟也能通过链接,难道是 GLFW 和 GLAD 其实是 C 写的库?
于是尝试写了一个简单的混合编译测试。
混合编译
写一个简单的加法和减法函数,然后加法使用 C++ 编写,减法使用 C 编写,并对加法、减法各自单独编译为一个导出动态库目标,同时再添加一个混合编译目标,混合编译动态库的源文件就是囊括了 add.cpp
和 sub.c
的库,我看看如果编译的时候混合了不同类型的源文件,那么编译好的库的导出符号表里面每个函数到底是什么符号。
目录结构如下:
C:.
│ CMakeLists.txt
│
├─build
│ ├─Debug
│ │ ├─bin
│ │ │ libadd.dll
│ │ │ libcalc.dll
│ │ │ libsub.dll
│ │ │
│ │ └─lib
│ │ libadd.dll.a
│ │ libcalc.dll.a
│ │ libsub.dll.a
│ │
│ ├─install
│ │ ├─bin
│ │ │ libadd.dll
│ │ │ libcalc.dll
│ │ │ libsub.dll
│ │ │
│ │ ├─include
│ │ │ ├─add
│ │ │ │ add.h
│ │ │ │
│ │ │ ├─include
│ │ │ │ ├─add
│ │ │ │ │ add.h
│ │ │ │ │
│ │ │ │ └─sub
│ │ │ │ sub.h
│ │ │ │
│ │ │ └─sub
│ │ │ sub.h
│ │ │
│ │ └─lib
│ │ │ libadd.dll.a
│ │ │ libcalc.dll.a
│ │ │ libsub.dll.a
│ │ │
│ │ └─cmake
│ │ └─calc
│ │ calcConfig.cmake
│ │ calcConfigVersion.cmake
│ │ calcTargets-debug.cmake
│ │ calcTargets.cmake
│
├─cmake
│ calcConfig.cmake.in
│
├─include
│ ├─add
│ │ add.h
│ │
│ └─sub
│ sub.h
│
└─src
add.cpp
CMakeLists.txt
sub.c
对两个函数各自写一个头文件放在 include
目录下对应的子目录里面,这样 CMake 编译的时候好分别为两个目标指定单独的头文件位置。然后 src
目录下分别使用 add.cpp
和 sub.c
实现 add
和 sub
函数。
头文件:
// add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif
// sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a, int b);
#endif
源文件:
// add.cpp
#include "add/add.h"
int add