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

0 c++ g++ linker-errors

这是在utils.hpp(NON 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);

Run Code Online (Sandbox Code Playgroud)

我对它们的定义utils.cpp包括utils.hpp

当我使用中的函数调用任何main函数时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*)
Run Code Online (Sandbox Code Playgroud)

编译命令:

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

将所有函数都定义为非静态,并且可以完美地进行编译!!我无法解决这个问题。

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

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

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

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("");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:这是我做事的方式main.cpp

k4a_calibration_t calibration;
k4a_image_t xy_table = NULL;
/*
Calibration initialization codes here
*/
create_xy_table(&calibration, xy_table);
Run Code Online (Sandbox Code Playgroud)

Evg*_*Evg 6

当将实现放入单独的编译单元(.cpp文件)时,当对象文件链接在一起时,您会要求链接器稍后找到这些实现。当将函数声明为时static,表示该函数在其他编译单元中不可见(这称为内部链接)。

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

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