转换到OS X Mavericks和XCode 5.0.1后,我再也不能优雅地将已编译的C文件(从gcc输出)链接到C ++项目(从g ++输出)。
从我的makefile生成的令人讨厌的命令对是:
gcc `pkg-config --cflags glib-2.0` -g -Wall -O3 `pkg-config --cflags flann` -c -o vec.o vec.c g++ `pkg-config --cflags glib-2.0` -g -Wall -O3 -stdlib=libstdc++ -lstdc++ layoutquality.cpp vec.o `pkg-config --libs glib-2.0` -L/usr/local/Cellar/flann/1.8.4/lib -lflann -o layoutquality
链接器抱怨的是:
体系结构x86_64的未定义符号:“load_dmat(char const *)”,引用自:layoutquality中的_main-I8HOqy.o ld:未找到体系结构x86_64的符号
其中load_dmat
只是文件vec.c中的一个函数。 如果我在第一行用g++
替换gcc
,那么一切都编译好并且链接很好,但clang说:
clang:警告:在C ++模式下将’c’输入视为’c ++’时,不推荐使用此行为
是否有一种无害的,不推荐的编译和链接方式? 在升级到OS X Mavericks和新命令行工具之前,将g++
与gcc
目标文件链接在一起工作正常。 任何有关变化和如何前进的见解都会很棒,谢谢。
在“vec.c”之前添加“-xc”(不带引号)应修复它。
如果在同一行中编译多个.c / .cpp文件,则可以在每个C或C ++文件名列表之前使用“-xc”或“-x c ++”来适当地切换上下文。 例如:
g++ -xc alpha.c beta.c -x c++ gamma.cpp
这是一个让我们在C
程序中使用C++
代码/函数的Makefile
示例。
CC=clang CXX=clang++ CFLAGS=-Wall -g CXXFLAGS=-Wall -g -std=c++11 -I. DEPS=CPP.h OBJ=main.o CPP.o RM=rm -f # compile only, C source %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) # compile only, C++ source %.o: %.cpp $(DEPS) $(CXX) -c -o $@ $< $(CXXFLAGS) # link main: $(OBJ) $(CXX) -o $@ $^ $(CXXFLAGS) clean: $(RM) $(OBJ)
如您所见,我们在两次单独的编译调用中使用CXXFLAGS
和CFLAGS
分别生成对象。 在使用Xcode的clang的Mac环境中,clang( CC
)和clang ++( CXX
)实际上是同一个东西。 只有不同的旗帜很重要。 我只是通过在上面的示例Makefile
陈述CC
和CXX
的定义而迂腐。
生成目标文件后,我们很高兴将它们链接在一起。
但请注意,您必须执行一个额外步骤才能使C++
代码可以使用C++
代码。
在本例中的CPP.h
中,您必须显式使用extern "C"
来指定C++
链接以供C++
使用。
例如,像这样:
#ifdef __cplusplus extern "C" { #endif double timesTwo(double number); #ifdef __cplusplus } #endif
预处理器宏#ifdef __cplusplus
和#endif
是为了确保我们的头文件不会导致C模式编译错误,并且只在C ++模式编译期间有效。
此完整示例仅包含4个文件。
上面解释了Makefile
源和CPP.h
为了完整的理解,我在这里也包括main.c
和CPP.cpp
。
main.c
:
#include #include "CPP.h" int main() { printf("Running main.cn"); double ans = timesTwo(3.0); printf("The answer from our C++ timesTwo function, when given 3.0, is %fn", ans); return 0; }
CPP.cpp
:
#include "CPP.h" double timesTwo(double number) { return 2 * number; }
我相信这个解释和示例阐明了我们如何设置我们的Makefile
,指定#ifdef __cplusplus
预处理器宏和extern "C"
链接声明以允许C ++ - to-C互操作,并且在运行make时没有错误的clang警告。
很可能你是Name mangling的受害者。 要避免在C ++中进行名称修改,请在声明周围使用extern "C"
,例如:
需要了解更多c/c++开发分享在OS X Mavericks中从C ++链接C语言,也可以关注C/ C++技术分享栏目---计算机技术网(www.ctvol.com)!
#ifdef __cplusplus extern "C" { #endif void load_dmat(char const*); #ifdef __cplusplus } #endif
以上就是c/c++开发分享在OS X Mavericks中从C ++链接C语言相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979158.html