声明和定义函数静态将产生“对function_name()的未定义引用”

时间:2019-11-21 05:54:48

标签: c++ g++ linker-errors

这是utils.hpp中定义的函数原型声明(非OOP,因此不在任何类中)

static void create_xy_table(const k4a_calibration_t *calibration, k4a_image_t xy_table);

static void generate_point_cloud(const k4a_image_t depth_image,
                                 const k4a_image_t xy_table,
                                 k4a_image_t point_cloud,
                                 int *point_count);

static void write_point_cloud(const char *file_name, const k4a_image_t point_cloud, int point_count);

我在utils.cpp中有它们的定义,其中包括utils.hpp

当我在main的{​​{1}}函数中使用任何函数时,会出现以下错误:

main.cpp

编译命令:

/tmp/ccFcMfYB.o: In function `main': main.cpp:(.text+0x208): undefined reference to `create_xy_table(_k4a_calibration_t const*, _k4a_image_t*)

将所有函数都定义为非静态的并且可以完美地进行编译!! 我对此一无所知。

  • 到底发生了什么?
  • 如果需要定义和链接静态函数,应该怎么做才能正确包含/链接?

我的系统配置: gcc版本7.4.0(Ubuntu 7.4.0-1ubuntu1〜18.04.1)

编辑: 这是我在utils.cpp中的函数定义:

g++ -o build/testtest src/main.cpp src/utils.cpp -I./include -lk4a

EDIT2 : 这是我在static void create_xy_table(const k4a_calibration_t *calibration, k4a_image_t xy_table) { k4a_float2_t *table_data = (k4a_float2_t *)(void *)k4a_image_get_buffer(xy_table); int width = calibration->depth_camera_calibration.resolution_width; int height = calibration->depth_camera_calibration.resolution_height; k4a_float2_t p; k4a_float3_t ray; int valid; for (int y = 0, idx = 0; y < height; y++) { p.xy.y = (float)y; for (int x = 0; x < width; x++, idx++) { p.xy.x = (float)x; k4a_calibration_2d_to_3d( calibration, &p, 1.f, K4A_CALIBRATION_TYPE_DEPTH, K4A_CALIBRATION_TYPE_DEPTH, &ray, &valid); if (valid) { table_data[idx].xy.x = ray.xyz.x; table_data[idx].xy.y = ray.xyz.y; } else { table_data[idx].xy.x = nanf(""); table_data[idx].xy.y = nanf(""); } } } } 中所做的事情。

main.cpp

2 个答案:

答案 0 :(得分:6)

将实现放入单独的编译单元(.cpp文件)中时,当对象文件链接在一起时,您会要求链接程序稍后找到这些实现。当您将函数声明为static时,就是说该函数在其他编译单元(即internal linkage)中不可见。

现在,您包含带有static函数的标头。 utils.cpp将获得其自己的副本,该副本对于所有其他编译单元均不可见。 main.cpp将仅看到声明,而看不到实现,因此将不会生成任何代码。这就是为什么出现链接错误的原因-代码位于utils.cpp中,但是任何人都无法访问。

如果出于某种原因想要包括static函数,则应在头文件中提供其实现。然后,每个编译单元将获得它们自己的私有副本。

答案 1 :(得分:0)

c / c ++中的

static修饰符将函数定义限制为一个编译单元(utils.cpp)。这些功能将无法通过其他编译单元查看/访问,例如您的情况下是main.cpp。