1. 程式人生 > 其它 >ROS c++內嵌c語言(一):c標頭檔案處理

ROS c++內嵌c語言(一):c標頭檔案處理

技術標籤:rosC++c++編譯器ros

背景

ROS開發過程中涉及到.cpp檔案呼叫.c檔案的函式,編譯時報警.c中被呼叫的函式未定義:
main_window.cpp:(.text+0x36dc):對‘jt_to_CartesianPose(float*,float*)’未定義的引用

CMakeFiles/qtros.dir/src/main_window.cpp.o:在函式‘qtros::MainWindow::update_listView_CartesianPose(sensor_msgs::JointState_<std::allocator<void> > const&)’中:
main_window.cpp:(.text+0x36dc):對‘jt_to_CartesianPose(float*,float*)’未定義的引用
collect2: error: ld returned 1 exit status
qtros/CMakeFiles/qtros.dir/build.make:557: recipe for target '/home/ros_gui_ws/catkin_ws/devel/lib/qtros/qtros' failed
make[2]: *** [/home/ros_gui_ws/catkin_ws/devel/lib/qtros/qtros] Error 1
CMakeFiles/Makefile2:1360: recipe for target 'qtros/CMakeFiles/qtros.dir/all' failed
make[1]: *** [qtros/CMakeFiles/qtros.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j3 -l3" failed

原因分析

在呼叫jt_to_CartesianPose前,cpp檔案對c語言標頭檔案的包含後,編譯正常,說明c檔案的包含關係是正確的。當呼叫具體函式時,編譯報警,分析是對jt_to_CartesianPose的外部宣告出現問題,導致cpp檔案無法找到jt_to_CartesianPose的路徑。

檢視 joint_to_CartesianPose 的 .h檔案,發現extern void joint_to_CartesianPose(float *joint_value,float *new_jt);被放到了extern "C"區域外側導致c++編譯器在編譯C語言函式時找不到連結路徑而報錯

#ifndef     _RC_MODEL_H_
#define     _RC_MODEL_H_

#ifdef __cplusplus
extern "C"{
#endif


#ifdef __cplusplus
}
#endif

extern void joint_to_CartesianPose(float *joint_value,float *new_jt); // (放到了extern "C"區域外)

#endif

解決方案

#ifndef     _RC_MODEL_H_
#define     _RC_MODEL_H_

#ifdef __cplusplus
extern "C"{
#endif

extern void joint_to_CartesianPose(float *joint_value,float *new_jt); // (調整到extern "C"區域內)

#ifdef __cplusplus
}
#endif

#endif

再次編譯,成功!

補充(重要)

__cplusplus巨集簡單介紹:

在C語言gcc編譯器中是沒有__cplusplus這個巨集,而g++預編譯之後,能夠識別__cplusplus這個巨集。

在使用c++編譯器編譯其他語言(這裡是C語言,得編譯器支援的語言)時,用上這樣的方式,可以讓編譯器把extern “C”程式碼塊中的內容按照C語言的編譯方式進行編譯。因為c++中支援函式過載,而C語言不支援,c++對函式經過了其他處理,如果不加extern “C”限制按照C語言的方式編譯,那麼c++編譯器在編譯C語言函式時可能就會找不到連結路徑而報錯

參考連結:https://www.cnblogs.com/yangguang-it/p/6720211.html