【问题标题】:Magick++ undefined reference to Magick::Image::ColumnsMagick++ 未定义对 Magick::Image::Columns 的引用
【发布时间】:2017-11-09 13:02:30
【问题描述】:

美好的一天, 这是我的代码

#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int main(int argc, char **argv) {
  InitializeMagick(*argv);
  Image image;
  try {
    image.read(argv[1]);
  } 
  catch( Exception &error_ ) {
    cout << "Caught exception: " << error_.what() << endl; 
      return 1; 
  } 
  int x = image.columns();
  cout<<"your picture's width is "<< x << "px"<<endl;
  return 0; 
}

我使用 KDevelop(它使用 CMake 作为构建器), 当我尝试编译应用程序时,它会抛出一个错误

main.cpp:25: 未定义引用 `Magick::Image::columns() const'

这是我的 CMakeLists.txt 包含的内容。

cmake_minimum_required(VERSION 3.5)
project(hello)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)

add_executable(hello ${SOURCE_FILES})
add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 )
add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 )
find_package(ImageMagick COMPONENTS Magick++)
include_directories(${ImageMagick_INCLUDE_DIRS})
target_link_libraries(hello ${ImageMagick_LIBRARIES})

我发现当 CMakeLists 编写不正确时,通常会出现未定义引用的问题,但我是根据这个 About Magick++, how to write the CMakeLists?

我哪里错了?我可以添加任何需要的信息。

UPD 1。 魔术师++的版本, 8:6.8.9.9-7ubuntu5.7

系统信息: 说明:Linux Mint 18.1 Serena

UPD 2。 我刚刚删除了括号,并在尝试编译时使用

size_t x = image.columns;
size_t y = image.rows;

KDevelop 把我扔了

main.cpp:25:22: 错误: 无法从类型 'size_t (Magick::Image::)() 转换 'Magick::Image::columns' const {aka long unsigned int (Magick::Image: :)() const}' 输入 'size_t {aka long unsigned int}'

即使

auto x = image.columns;
auto y = image.rows;

它抛出

main.cpp:25:20: 错误: 无法将‘Magick::Image::columns’从 输入‘size_t (Magick::Image::)() const {aka long unsigned int (Magick::Image::)() const}' 输入'long unsigned int (Magick::Image::*)() const'

发生了什么事?

附:万岁,这是我关于stackoverflow的第一个问题! :-)

【问题讨论】:

  • 尝试将int x 切换为size_t x。能否介绍一下安装的 ImageMagick 的系统和版本?
  • @emcconville 感谢您的提示,但没有帮助,仍然抛出同样的错误
  • 不带括号的错误消息表明它无法将不带参数 (()) 并返回 size_t 的方法 ((Magick::Image::)) 转换为值(size_t 类型)。换句话说,您需要括号,因为它是您应该调用的函数。 (对于auto,它不能将方法转换为方法指针(Magick::Image::*)。)
  • 你可以尝试用g++ main.cpp `Magick++-config --cxxflags --cppflags --ldflags --libs` 编译,看看它是否有效?

标签: c++ imagemagick magick++


【解决方案1】:

如果您能够在不使用 CMake 的情况下使用 g++ main.cpp `Magick++-config --cxxflags --cppflags --ldflags --libs` 编译程序(但由于某种原因不能在 CMake 中使用 ${ImageMagick_LIBRARIES}),那么您可以在 CMakeLists.txt 中使用 Magick++-config:

cmake_minimum_required(VERSION 3.5)
project(hello LANGUAGES CXX)

add_executable(hello main.cpp)
target_compile_features(hello PRIVATE cxx_std_11)
find_package(ImageMagick REQUIRED COMPONENTS Magick++)
target_compile_definitions(hello PRIVATE
  MAGICKCORE_QUANTUM_DEPTH=16
  MAGICKCORE_HDRI_ENABLE=0
)
target_include_directories(hello PRIVATE ${ImageMagick_INCLUDE_DIRS})

execute_process(COMMAND Magick++-config --ldflags
  OUTPUT_VARIABLE ImageMagick_LINK_FLAGS
  OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_link_libraries(hello PRIVATE ${ImageMagick_LINK_FLAGS})

这里,execute_process 允许我们将Magick++-config --ldflags 的结果放入一个变量中,我们可以通过target_link_libraries 将其作为标志传递给链接器。

另外,请注意我是如何使用target_compile_features 而不是设置全局CMAKE_CXX_FLAGS 变量、target_compile_definitions 而不是add_definitions 和target_include_directories 而不是include_directories。在编程和 CMake 中,最好使用本地(基于目标)命令而不是修改全局状态,因为它们可能会产生不可预见的影响——在 CMake 的上下文中,这些全局命令会影响嵌套子项目。

【讨论】:

    【解决方案2】:

    我改编的 ForgottenUbrella 版本不太适合我,从另一个项目中复制一行修复了它。注意,我使用的是 c++20 而不是 11。

    我遇到了以下错误:

    ..... undefined reference to symbol 'pthread_create@@GLIBC_2.2.5'
    

    以及修复它的行:

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2a -pthread")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-10-16
      • 2014-05-20
      • 1970-01-01
      • 2015-01-08
      相关资源
      最近更新 更多