在 CMake 中包含 C File/Linking 不适用于 C++:无法包含函数
Including C File/Linking with CMake isn't working with C++: cannot include function
这是我的 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 is.I 使用 gcc 编译它并正在尝试 link 该库。
这是我的 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中定义的这个函数?
所以你有 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
.
如果没有这些定义,您的编译器将不知道您是否将正确数量的 and/or 类型的参数传递给这些函数。它不知道函数的 return 类型是什么,或者它是否没有。
在 C++ 中,此信息尤其重要,因为您有函数重载,因此它必须准确知道您正在调用哪个函数。在 C 中,它并没有那么严格,并且会做出关于函数的假设——这些假设通常是不正确的,但它仍然会警告你它已经完成了。
在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 警告。
如果我使用以下来源
#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。
这是我的 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 is.I 使用 gcc 编译它并正在尝试 link 该库。
这是我的 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中定义的这个函数?
所以你有 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
.
如果没有这些定义,您的编译器将不知道您是否将正确数量的 and/or 类型的参数传递给这些函数。它不知道函数的 return 类型是什么,或者它是否没有。
在 C++ 中,此信息尤其重要,因为您有函数重载,因此它必须准确知道您正在调用哪个函数。在 C 中,它并没有那么严格,并且会做出关于函数的假设——这些假设通常是不正确的,但它仍然会警告你它已经完成了。
在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 警告。
如果我使用以下来源
#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。