C和C++混编

最近的项目需要在.c文件里面调用.cpp文件中的函数,以及在cpp中调用c文件函数,用到了c/c++混合编译,在这里记录一下。

makefile大致思路:

 调用g++将所有.cpp文件编译成.o文件,调用gcc将所有.c文件编译成.o文件;

 调用g++将所有的.o文件链接成可执行文件;

步骤很简单,唯一要注意的是在.c文件对应的头文件中一定需要加上

#ifdef __cplusplus
extern "C"
{
#endif

/* 函数声明代码块 */

#ifdef __cplusplus
}
#endif

否则在链接的时候会出现 undefined reference to 的错误。

 

示例 Makefile:

TARGET = pdif
OBJ_PATH = objs
PREFIX_BIN = ./
SRC = ./

CROSS_COMPILE=arm-linux-gnueabihf-
CC = $(CROSS_COMPILE)gcc
CPP = $(CROSS_COMPILE)g++

#include path
INCLUDES = -I ./$(SRC)app

#source path
SRCDIR = $(SRC)app


#buid to object files
#C_SOURCES = $(wildcard *.c)
C_SRCDIR = $(SRCDIR)
C_SOURCES = $(foreach d,$(C_SRCDIR),$(wildcard  $(d)/*.c) )
C_OBJS = $(patsubst %.c, $(OBJ_PATH)/%.o, $(C_SOURCES))

#CPP_SOURCES = $(wildcard *.cpp)
CPP_SRCDIR = $(SRCDIR)
CPP_SOURCES = $(foreach d,$(CPP_SRCDIR),$(wildcard  $(d)/*.cpp) )
CPP_OBJS = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(CPP_SOURCES))

default:init compile

#buid c files
$(C_OBJS):$(OBJ_PATH)/%.o:%.c
	$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
#buid c++ files
$(CPP_OBJS):$(OBJ_PATH)/%.o:%.cpp
	$(CPP) -c $(CPPFLAGS) $(INCLUDES) $< -o $@

init:
	$(foreach d,$(SRCDIR), mkdir -p $(OBJ_PATH)/$(d);)

test:
	@echo "C_SOURCES: $(C_SOURCES)"
	@echo "C_OBJS: $(C_OBJS)"
	@echo "CPP_SOURCES: $(CPP_SOURCES)"
	@echo "CPP_OBJS: $(CPP_OBJS)"
	@echo "INCLUDES: $(INCLUDES)"
#link
compile:$(C_OBJS) $(CPP_OBJS)
	$(CPP)  $^ -o $(TARGET)  $(LINKFLAGS) $(LIBS)

clean:
	rm -rf $(OBJ_PATH)
	rm -f $(TARGET)

install: $(TARGET)
	cp $(TARGET) $(PREFIX_BIN)

uninstall:
	rm -f $(PREFIX_BIN)/$(TARGET)

rebuild: clean init compile

 

Fortran和C++可以通过一些接口来实现混编,以下是一个简单的示例: 首先是Fortran程序,其中包含了一个Fortran函数和一个接口: ``` ! sample.f90 module sample implicit none contains ! Fortran函数 real function func(x) real, intent(in) :: x func = x**2 + 2*x + 1 end function func ! 接口 interface real function cplusplus_func(x) bind(C, name="cplusplus_func") import :: C_DOUBLE real(C_DOUBLE), intent(in) :: x end function cplusplus_func end interface end module sample ``` 接着是C++程序,其中包含了一个C++函数和一个接口: ``` // sample.cpp #include <iostream> using namespace std; extern "C" { // C++函数 double cplusplus_func(double x) { return x*x + 2*x + 1; } // 接口 extern double func_(double *x); } int main() { double x = 2.0; // 调用C++函数 double y = cplusplus_func(x); cout << "C++ function: " << y << endl; // 调用Fortran函数 double z = func_(&x); cout << "Fortran function: " << z << endl; return 0; } ``` 在C++程序中,我们使用了`extern "C"`来声明C++函数和接口,以便在链接时能够正确地找到它们。在主函数中,我们首先调用了一个C++函数,然后通过接口调用了一个Fortran函数。 编译Fortran程序时,需要使用`-c`选项生成静态库文件: ``` $ gfortran -c sample.f90 ``` 编译C++程序时,需要链接静态库文件,并使用`-lstdc++`选项链接C++标准库: ``` $ g++ sample.cpp sample.o -lstdc++ ``` 运行程序,可以得到如下输出: ``` C++ function: 9 Fortran function: 9 ``` 说明我们成功地实现了Fortran和C++混编
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值