Не могу связать libtiff

Я пытаюсь создать программу на С++ с помощью Microsoft Visual Studio 2017.

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
extern "C" {
     #include "libtiff/libtiff/tiffio.h"
}

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
string imageName("410.tif"); // start with a default

                             // If there is an argument, read it in as the name of the image
if (argc > 1)
{
    imageName = argv[1];
}

// Open the TIFF file using libtiff
TIFF* tif = TIFFOpen(imageName.c_str(), "r");

// Create a matrix to hold the tif image in
Mat image;

// check the tif is open
if (tif) {
    do {
        unsigned int width, height;
        uint32* raster;

        // get the size of the tiff
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);

        uint npixels = width * height; // get the total number of pixels

        raster = (uint32*)_TIFFmalloc(npixels * sizeof(uint32)); // allocate temp memory (must use the tiff library malloc)
        if (raster == NULL) // check the raster's memory was allocaed
        {
            TIFFClose(tif);
            cerr << "Could not allocate memory for raster of TIFF image" << endl;
            return -1;
        }

        // Check the tif read to the raster correctly
        if (!TIFFReadRGBAImage(tif, width, height, raster, 0))
        {
            TIFFClose(tif);
            cerr << "Could not read raster of TIFF image" << endl;
            return -1;
        }

        image = Mat(width, height, CV_8UC4); // create a new matrix of w x h with 8 bits per channel and 4 channels (RGBA)

                                             // itterate through all the pixels of the tif
        for (uint x = 0; x < width; x++)
            for (uint y = 0; y < height; y++)
            {
                uint32& TiffPixel = raster[y*width + x]; // read the current pixel of the TIF
                Vec4b& pixel = image.at<Vec4b>(Point(y, x)); // read the current pixel of the matrix
                pixel[0] = TIFFGetB(TiffPixel); // Set the pixel values as BGRA
                pixel[1] = TIFFGetG(TiffPixel);
                pixel[2] = TIFFGetR(TiffPixel);
                pixel[3] = TIFFGetA(TiffPixel);
            }

        _TIFFfree(raster); // release temp memory
                           // Rotate the image 90 degrees couter clockwise
        image = image.t();
        flip(image, image, 0);
        imshow("TIF Image", image); // show the image
        waitKey(0); // wait for anykey before displaying next
    } while (TIFFReadDirectory(tif)); // get the next tif
    TIFFClose(tif); // close the tif file
}
    return 0;
}

Как видите, я включаю libtiff, но при попытке скомпилировать получаю следующую ошибку:

Ссылка LNK2019 на внешний символ _TIFFmalloc не разрешена в функции

Ошибка распространяется на "_TIFFfree,TIFFClose, TIFFGetField, TIFFReadDirectory, TIFFReadRGBAImage, TIFFOpen" (для удобства я разместил только один).

Я попытался найти в Google информацию об этой проблеме и думаю, что это связано с проблемой связывания. Многие люди говорили, что я должен добавить «libtiff.lib» в раздел «ввод» свойств проекта Visual Studio, но у меня нет libtiff.lib в библиотеке, которую я скачал из официального источника.

Я использую версию библиотеки 4.0.4.


person Davide57    schedule 02.08.2018    source источник
comment
Поскольку они предназначены для переносимости, вам нужно предоставить их или ссылку на версию для вашей платформы?   -  person William J Bagshaw    schedule 02.08.2018
comment
Также у вас есть прототип для этого. Возможно, это должны быть прототипы C.   -  person William J Bagshaw    schedule 02.08.2018
comment
@WilliamJBagshaw, если бы они уже не были прототипами C, разве в сообщении об ошибке не отображалось бы украшенное имя?   -  person Mark Ransom    schedule 02.08.2018
comment
Я не уверен, что понимаю, проблема в том, что они недоступны на С++? Как я должен это исправить? Я тоже пытался добавить extern C, но ничего не изменилось.   -  person Davide57    schedule 02.08.2018
comment
@Davide57 Davide57 Вы не связались с libtiff.lib, с чем вы связались и как вы это сделали?   -  person john    schedule 02.08.2018
comment
@ Davide57 Теперь совершенно ясно, что вы не связываетесь с библиотекой tiff. Все используемые вами функции не разрешены. Недостаточно #include, вы должны также связать. Перечитайте документацию.   -  person john    schedule 02.08.2018
comment
@john Да, но, как я уже сказал, я не могу сделать ссылку, потому что в библиотеке нет libtiff.lib. Есть ли другой способ связать библиотеку с Visual Studio 2017?   -  person Davide57    schedule 02.08.2018
comment
@Davide57 Может быть, у вас есть дистрибутив только с исходным кодом, и вы должны сами собрать библиотеку? Я не знаю, я не вижу, на что ты смотришь.   -  person john    schedule 02.08.2018
comment
@john Я скачал версию 4.0.4 отсюда: download.osgeo.org/libtiff Я пытался с другими версиями тоже, но я нигде не могу найти этот файл libtiff.lib. Может у файла другое расширение?   -  person Davide57    schedule 02.08.2018
comment
Есть два Makefile (.in и .am), как их использовать для компоновки библиотеки? @Джон   -  person Davide57    schedule 02.08.2018
comment
@Davide57 Это исходный выпуск с процессом сборки Unix. Возможно, вы сможете собрать его в Windows, если загрузите что-то вроде Cygwin. Но на самом деле я думаю, что вам лучше поискать дистрибутив libtiff для Windows.   -  person john    schedule 02.08.2018
comment
@john Мне нужно использовать его в Windows...   -  person Davide57    schedule 03.08.2018
comment
@Davide57 Ты этого хочешь? gnuwin32.sourceforge.net/packages/tiff.htm   -  person john    schedule 03.08.2018
comment
Да, @john, теперь, используя эту библиотеку, я получил файл .lib и могу связать его, но проблема в том, что у меня возникла проблема: обратите внимание на LNK4272, тип «x86» библиотечного компьютера конфликтует с типом «x64» цели. компьютер ImageManipulation C:\Program Files (x86)\GnuWin32\lib\libtiff.lib 1 Решение для платформы установлено на x64, и я должен поддерживать это из-за openCV...   -  person Davide57    schedule 03.08.2018
comment
@ Davide57 Ну, может быть, другая библиотека? Кажется, libtiff не для вас.   -  person john    schedule 03.08.2018
comment
@john Я успешно добавил libtiff и нашел openCV с 64-битной версией (datapacket.dl.sourceforge.net/project/opencvlibrary/opencv-win/) Поэтому я могу использовать его в режиме x86, но в этой версии openCV нет global.lib и когда я пытаюсь добавить все файлы .lib, я получаю следующие ошибки:   -  person Davide57    schedule 03.08.2018
comment
›Source.obj: ошибка LNK2019: неразрешенный внешний символ private: char * __thiscall cv::String::allocate(unsigned int) (?allocate@String@cv@@AAEPADI@Z), указанный в функции public: __thiscall cv::String ::String(class std::basic_string‹char,struct std::char_traits‹char›, class std::allocator‹char› › const &) (??0String@cv@@QAE@ABV?$basic_string@DU? $char_traits@D@std@@V?$allocator@D@2@@std@@@Z)   -  person Davide57    schedule 03.08.2018
comment
1>Source.obj: ошибка LNK2019: неразрешенный внешний символ private: void __thiscall cv::String::deallocate(void) (?deallocate@String@cv@@AAEXXZ), указанный в публичной функции: __thiscall cv::String::~ String(void) (??1String@cv@@QAE@XZ) 1>Source.obj : error LNK2019: неразрешенный внешний класс символов cv::Mat __cdecl cv::imread(class cv::String const &,int) ( ?imread@cv@@YA?AVMat@1@ABVString@1@H@Z), на который ссылается функция _main   -  person Davide57    schedule 03.08.2018
comment
@Davide57 Davide57 Догадка, но у вас все еще есть старая установка OpenCV? Похоже, вы можете использовать файлы заголовков из вашего старого OpenCV, но файлы библиотеки из вашего нового OpenCV. Удалите старый OpenCV и попробуйте еще раз, возможно.   -  person john    schedule 04.08.2018


Ответы (2)


TIFF — это библиотека C, в то время как ваша программа написана на C++, C++ и C имеют разные ABI для связывания.

Когда вы используете библиотеку C из исходного кода C++, вы обычно должны делать что-то вроде:

extern "C" {
    #include "libtiff/libtiff/tiffio.h"
}

... чтобы сигнализировать С++ о том, что эти символы следуют за C ABI.

ПРИМЕЧАНИЕ. Многие широко используемые библиотеки C включают условные проверки препроцессора C++ внутри своих заголовков, чтобы избежать этой проблемы, например:

#ifdef __cplusplus
extern "C" {
#endif
/* Actual header content */
extern int do_something(void); 
extern int do_something_else(const char*); 
/* ... */
#ifdef __cplusplus
}
#end

Это не относится к libtiff.

person gabry    schedule 02.08.2018
comment
Я уверен, что вы правы, но почему _TIFFmalloc единственный неразрешенный. - person john; 02.08.2018
comment
Я попытался добавить то, что вы сказали, но проблема не устранена. В любом случае, @john, проблема распространяется на все _, но я опубликовал только один. - person Davide57; 02.08.2018
comment
@Davide57 Просто предположение, но, может быть, функции _ определены в другой библиотеке, с которой вы не связываетесь? - person john; 02.08.2018
comment
@john Проблема в _TIFFMalloc, _TIFFfree, TIFFClose, TIFFGetField, TIFFReadDirectory, TIFFReadRGBAImage, TIFFOpen. Я не имею понятия почему... - person Davide57; 02.08.2018

Используя следующую библиотеку: http://gnuwin32.sourceforge.net/packages/tiff.htm Я могу правильно включить libtiff, но проблема в том, что эта библиотека 64-битная, а openCV 32-битная. Итак, я получаю следующую ошибку:

LNK4272 тип "x86" компьютера библиотеки конфликтует с типом "x64" целевого компьютера ImageManipulation C:\Program Files (x86)\GnuWin32\lib\libtiff.lib 1

Платформенное решение в Visual Studio настроено на x64, потому что, если я включу его, x86 openCV не будет работать.

person Davide57    schedule 03.08.2018