【问题标题】:Including C File/Linking with CMake isn't working with C++: cannot include function包含 C 文件/使用 CMake 链接不适用于 C++:不能包含函数
【发布时间】:2017-06-23 13:30:54
【问题描述】:

这是我的 C++ 代码:

#include "stdlib.h"
#include "stdio.h"
#include <iostream>


int main(int argc, char *argv[] ) {     
    int width, height;
    unsigned char *rgba;
    FILE *fp = fopen("/home/pic.tif", "rb");
    if(!fp)
        std::cout<<"failed"<<std::endl;
    rgba = floadtiff(fp, &width, &height);
    fclose(fp);

    if(rgba == 0)
        printf("TIFF file unreadable\n");
}

我正在使用@MalcolmMcLean 的this 库,这就是我的loadtiff.c。我已经使用gcc 对其进行了编译,并且正在尝试链接该库。

这是我的 CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
target_link_libraries(test loadtiff)

这些是我在尝试制作程序时遇到的错误:

error: ‘floadtiff’ was not declared in this scope

为什么我无法访问这个在 loadtiff.c 中定义的函数?

【问题讨论】:

  • 您确定包含正确的文件吗? #include 通常用于包含头文件,而不是源文件。
  • 如果这是 C++,为什么还要包含 C 头文件(即 stdio.h)以及 C++ 头文件?
  • @ChrisTurner 我以为 stdio.h 是 C++ 头文件,我不知道!是的,我认为那是正确的文件,他说只需将其放入并编译?
  • 在您的 tiffs.cpp 文件中,您需要包含 #include "loadtiff.h" 而不是 loadtiff.c
  • 请将您的 loadtiff 库编译为静态库而不是共享对象。通过将 add_library(loadtiff STATIC loadtiff.c) 添加到您的 CMakeLists.txt 中。然后在您的 tiffs.cpp 文件中添加 extern "C" { #include "loadtiff.h" } 行。

标签: c++ c cmake linker shared-libraries


【解决方案1】:

tipps.cpp 中添加:

extern "C" {
#include "loadtiff.h" 
}

CMakeLists.txt 更改为:

cmake_minimum_required(VERSION 2.8.12.2)
project(tiffs)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_library(loadtiff tiffloader/loadtiff.c)
target_include_directories(loadtiff PUBLIC tiffloader/loadtiff.h)

add_executable(tiffs tiffs.cpp)
target_link_libraries(tiffs loadtiff)

“tiffloader/”是放置“loadtiff”文件的位置。

不要以“test”之类的保留字命名项目或目标,否则会收到 CMake 警告。

【讨论】:

  • 谢谢,这成功了!!!!!!具有讽刺意味的是,在这一切之后,该库不适用于我的图像类型。
【解决方案2】:

所以你有两个问题。

1) 你的代码是 C 和 C++ 的混合体。例如,您正在使用 C++ 输出文本

std::cout<<"failed"<<std::endl;

和C

printf("TIFF file unreadable\n");

只选择一种语言并坚持下去。鉴于floadtiff 似乎期待FILE *,您最好用C 编写代码。

2) 你试图使用一个库而不告诉编译器任何关于它的事情。这就是头文件的用途。它们告诉编译器您正在使用来自不同文件的代码以及如何调用该文件中的函数。某处应该有一个“loadtiff.h”文件——你需要包含它。这将包含“loadtiff.c”中函数的定义,例如floadtiff

如果没有这些定义,您的编译器将不知道您是否向这些函数传递了正确数量和/或类型的参数。它不知道函数的返回类型是什么或是否没有。

在 C++ 中,此信息尤其重要,因为您有函数重载,因此它必须准确知道您正在调用哪个函数。在 C 语言中,它并没有那么严格,并且会对函数做出假设(通常是不正确的),但它仍然会警告您它已经完成了这个。

【讨论】:

  • 按照您的建议并执行extern "C" {#include "loadtiff.h"} 后,我仍然收到未定义floadtiff 的错误。
  • “loadtiff.c”中是否有一个名为“floadtiff”的函数? “loadtiff.h”是否也有匹配的定义?
  • 是的!您可以从我的问题中的链接中验证是否需要,
【解决方案3】:

如果我使用以下来源

#include <cstdlib>
#include <cstdio>
#include <iostream>

extern "C" {
  #include "loadtiff.h"
}

int main(int argc, char argv[] ) {     
    int width, height;
    unsigned char* rgba;
    FILE* fp = fopen("/home/user/pic.tif", "rb");
    if(!fp)
        std::cout << "failed" << std::endl;
    rgba = floadtiff(fp, &width, &height);
    fclose(fp);

    if(rgba == 0)
        printf("TIFF file unreadable\n");
    return 0;
}

在 Visual Studio 14 和 CMake 3.8.2 下使用以下 CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8.12.2)
project (test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} cmake/)
add_executable(test tiffs.cpp)
add_library(loadtiff STATIC loadtiff.c)
target_link_libraries(test loadtiff)

CMake 生成一个功能齐全的解决方案,Visual Studio 能够毫无错误地构建它。

编辑:

我假设您的 tiffs.cpp、loadtiff.c 和 loadtiff.h 位于同一目录中。

【讨论】:

    猜你喜欢
    • 2021-10-29
    • 2019-06-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多