Integrating exiv2 with qt

Added by SAITEJA Tallam 11 months ago

Hi

I am trying to integrate exiv2 library with qt but when I tried to use a function, I get an error "undefined reference to".

I have written based on the code in this linkhttp://www.exiv2.org/examples.html example1.

MainWindow.cpp

void MainWindow::on_actionLoad_Image_triggered() {
fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), QDir::homePath(), tr("Image Files (*.png *.jpg *.bmp)"));
QFile file(fileName);
if(!file.exists()) return;
std::string pth = fileName.toStdString();
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(pth);

}

.pro file

win32: LIBS += -L$$PWD/libs/exif/lib/ -llibexiv2.dll
win32: LIBS += -L$$PWD/libs/exif/lib/ -llibz.dll
win32: LIBS += -L$$PWD/libs/exif/lib/ -llibexpat.dll
win32: LIBS += -L$$PWD/libs/exif/lib/ -lexiv2
win32: LIBS += -L$$PWD/libs/exif/lib/ -lz
win32: LIBS += -L$$PWD/libs/exif/lib/ -lexpat

INCLUDEPATH += $$PWD/libs/exif/include
DEPENDPATH += $$PWD/libs/exif/include

Qt Version and Kit Details:
Qt 5.6.1 MinGW 32 bit

Error:

C:...\exifData\mainwindow.cpp:23: error: undefined reference to `Exiv2::ImageFactory::open(std::string const&, bool)'

Any help in this regard please.


Replies (24)

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

The message sounds like a linker error so I don't think you're linking the library correctly. I think you may have to link the file libexiv2.dll.a That's a library (.a in Unix/MinGW) that knows how to operate with your dll. So, link the library and he'll use the DLL at run-time.

There are notes about Qt here: http://clanmills.com/exiv2/qt.shtml

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

I have made the changes but it still returns the same error

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

It's impossible for me to debug this for you from a single error message. Here are my suggestions:

1) The subject of Qt/MinGW has arise and been discussed in the Forum several times. Can you use "Search" on the forum to see if there's something like this which has been resolved in the past?
2) You try again. I did get this to work and have documented it. It will work if you try hard enough.
3) Bundle your project directory into a a zip and attach it to this discussion.
4) If you built the MinGW libexiv2 library from source, can you attach the .dll and .dll.a for me to test?
5) I can discuss it with you on an Instant Messenger such as Skype or Google Plus or Facebook.

Robin

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

Oh, here's another couple of suggestions.

1 Use absolute paths in the .pro file.

$$PWD is presumably your current directory. However, it could be almost anywhere (where qmake is running, quake's own directory, your home directory - and probably many other possibilities. Use an absolute path and get your code to link. Once it's working, you can go back an use environment strings to locate the libraries.

2 Format the absolute paths as documented:

 $$quote(C:/MinGW/msys/1.0/local/include) 
3 Avoid paths with a space ' ' in their name such as c:\Program Files

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Hi

This is what I have used in the .pro file

win32 {
INCLUDEPATH += $$quote(C:/MinGW/msys/1.0/local/include)
INCLUDEPATH += $$quote(C:/MinGW/msys/1.0/local/bin)
LIBS += $$quote(C:/MinGW/msys/1.0/local/lib/libexiv2.dll.a)
}

but there seems to be no difference. I get the same error

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

Please attach your binaries and send them to me. Zip up the /usr/local directory. And please attach your project files and code. I will have to install Qt 5.6.1 MinGW 32 bit on my machine because I haven't used Qt for a few years.

I would not be demotivated if you had the courtesy to say "Thank You, Robin for your time and helping me. I know you are an unpaid volunteer."

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Hi Robin

First of all, I am really sorry for my behavior. I have installed many softwares so my local dir is very large (200 MB). SO I am attaching only the files related to exifv2. Please tell me if I need to attach any other dependent libraries also. I have also attached the Qt code dir. Thank you Robin for your time and instant replies.

local.zip - local files having exif binaries only (1.59 MB)

exifData.zip - Qt files (7.41 MB)

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

That's more like the thing. Thank You for taking the time and interest to use Exiv2.

My machine has installed Qt 5.6. I'll look at your code this afternoon. (it's 14:04 in England).

Exiv2Logo.png (15.2 KB)

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Thank You!! Please do tell me if you require anyother details from my side

RE: Integrating exiv2 with qt - Added by Alan Pater 11 months ago

libkexiv2 does not do the job?

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Hi Alan

No. I have successfully compiled a simple main.cpp from the mingw terminal by this command:

g++ -IC:/MinGW/msys/1.0/local/include/ -LC:/MinGW/msys/1.0/local/bin/ -lexiv2-14 main.cpp

I have tried including and linking the same libraries with Qt but it does not do the job.

Thanks

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

I've got this to link and start. Then it crashes (discussed below). However, this is good step forward.

I'm using the Qt 5.6 command console. I've set the local\bin on the path:

set "PATH=%PATH%;c:\MinGW\msys\1.0\local\bin"
And I moved the .dll's into the bin:
C:\MinGW\msys\1.0\local>dir/s *.dll
 Volume in drive C has no label.
 Volume Serial Number is 0899-EF40

 Directory of C:\MinGW\msys\1.0\local\bin

09/02/2016  12:25 PM         3,813,237 libexiv2-14.dll
10/14/2014  10:19 AM           633,171 libexpat-1.dll
10/14/2014  10:33 AM           108,544 zlib.dll
10/14/2014  10:33 AM           108,544 zlib1.dll
               4 File(s)      4,663,496 bytes

     Total Files Listed:
               4 File(s)      4,663,496 bytes
               0 Dir(s)  21,487,067,136 bytes free

C:\MinGW\msys\1.0\local>

I modified your code:

// mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
#include <exiv2/exiv2.hpp>
#include <string>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionLoad_Image_triggered()
{
    fileName =  QFileDialog::getOpenFileName(this,tr("Open Image"), QDir::homePath(), tr("Image Files (*.png *.jpg *.bmp)"));
    QFile file(fileName);
    if(!file.exists()) return;
    std::string path = fileName.toStdString();                    // <--- get the path
    const Exiv2::byte* b    = (const Exiv2::byte*) path.c_str();  // <--- pointer to c_str
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(b,0); // <--- open it
}
And I modified your project file:
#-------------------------------------------------
# exifData.pro
# Project created by QtCreator 2016-09-02T17:16:51
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = exifData
TEMPLATE = app

SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

win32 {
    INCLUDEPATH  += $$quote(C:/MinGW/msys/1.0/local/include)
    INCLUDEPATH  += $$quote(C:/MinGW/msys/1.0/local/bin)
    LIBS         += -L$$quote(C:/MinGW/msys/1.0/local/lib) -lexiv2.dll
    // <- -L to add a library search path -lexiv2.dll to link libexiv2.dll.a
}
It links and runs. It doesn't start. It dies a horrible death on start up.

How to fix it?

I'm not sure how you obtained the build of the library. It's v0.24. I'd like to see you upgrade to a more current release. And I'd like to see the code compiled on the build machine with the tools being being used by Qt/MinGW.

I'm attempting to do that at the moment. It's complaining about can't find zlib and expat. I think I'll have to build them from source.

Anyway, you should be able to move ahead with this information. For sure, I don't believe there is anything wrong. It's hard work to get code up and running on an unfamiliar platform. I haven't worked with Qt/MinGW for more than 5 years.

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

Stellarium also uses zlib and here's their recipe to build their library to run on MinGW with Qt5: http://stellarium.sourceforge.net/wiki/index.php/Compile_with_MSYS_and_Qt5

Complicated. Yes, think so. MinGW is my least favourite build platform. Our buildserver builds on-demand and runs our test suite on MinGW. It uses the TDM-GCC-64 tool chain for 64 bit builds. It took quite an effort to get it to work. I suspect it's going to take quite a lot of work to get expat/zlib/exiv2 to build on the Qt/MinGW 492 platform. For sure, when I try to build zlib, ./configure reports errors with sed. Something equally unpleasant with expat.

The alternative is to use Qt/msvc_2013 (or 2015). You can build exiv2 for either of those platforms. We build them every night and you can download them from our buildserver. We even build and include the zlib and expat DLLs, libraries and headers. A much easier way to go.

Anyway, Mr T. I got up this morning at 6am to try to get to exiv2 v0.26 feature-complete today. I've spent 6 hours on this investigation. I want to return to my primary mission (very close, making good progress).

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Thanks a lot Robin. I have actually built the latest version (exisV2-0.25) and sent those binaries. If needed I can add those binaries also and send. I will try from my side based on the hints given.

I had one more doubt. Is it possible to add the source to Qt project and build or it will still have problems with expat and zlib. Once again Thanks for your precious time and

exiv2_vsn.PNG - version (32.4 KB)

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

As you have suggested, I have made the changes and it is crashing at start. I have found this error when I ran it through the debugger.

during startup program exited with code 0x0000c135

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

If you have built v0.25, you sent me v0.24 include files. That's a problem. It's essential to align the headers, library and dll.

I'm not going to do anything more on this for several reasons:

1) I'm really busy. I want to get to exiv2 v0.26 feature complete. I'll never get there if I keep working on other folk's stuff. 12 hour days are not fun.

2) I honestly don't believe this is an issue for Exiv2 because it has worked in the past.

3) Please remember that open-source is exactly that. You get source-code. Building that on different platforms is another matter. We provide a lot of build support and have a build server. None-the-less, I can't jump into an investigation of building the code on a platform that I've never used.

4) I find MinGW to be a very obstinate platform. I haven't used it a lot. I'd use it more if it were not so obstinate. If I used it more, it wouldn't be so obstinate.

You might be able to build libexiv2 with QtCreator and link everything together. You will need expat and zlib. And you will have to build xmpsdk (which is a static library that is built and linked by exiv2). I don't think it's a trivial project to build libexiv2 with QtCreator. It's possible, however QtCreator is not a supported build environment.

Qt 5.6 appears to be using GCC 4.9.2 which I believe defaults to C++11. It warns constantly about deprecated AutoPtr. Supporting C++11 (and C++14) is on the feature list for v0.27 #1188). http://dev.exiv2.org/projects/exiv2/news I believe the flag CXXFLAGS=-std=c++98 compiles "traditional" C++.

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

I am totally certain about what is wrong here. However I haven't been able to get it to build yet. I will on Wednesday.

What's wrong is that the header files and the libraries are different. So when you compile Exiv2::ImageFactory::open(const std::string&) from your headers and the name is appropriately mangled. However the library was compiled with different headers which do not have that entry point. That's what's wrong.

I've built exiv2 from the trunk using the autotools in the Qt 5.6 for Desktop Console. I've set some environment PATH variables:

c:\Users\rmills\gnu\exiv2\trunk>set | grep PATH
BINARY_PATH=/cygdrive/c/MinGW/msys/1.0/local/bin
INCLUDE_PATH=/cygdrive/c/MinGW/msys/1.0/local/include
LIBRARY_PATH=/cygdrive/c/MinGW/msys/1.0/local/lib
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig

c:\Users\rmills\gnu\exiv2\trunk>
And the path has been set to use the Qt Tools AND to the location of the MinGW bash shell right at the top:
c:\Users\rmills\gnu\exiv2\trunk>echo %PATH%
c:\Qt\Qt5.6.0\Tools\mingw492_32\bin;c:\MinGW\msys\1.0\bin;C:\Qt\Qt5.6.0\5.6\mingw49_32\bin;C:\Qt\Qt5.6.0\Tools\mingw492_32\bin;C:\Program Files (x86)\Parallels\Parallels Tools\Applications;C:\Program Files\7-Zip;C:\Program Files (x86)\WANdisco\Subversion;C:\ProgramData\Oracle\Java\javapath;C:\Python34\;C:\Python27\;C:\Python27\Scripts;C:\Perl64\site\bin;C:\Perl64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\TDM-GCC-64\bin;C:\Program Files (x86)\WinMerge;C:\Users\rmills\com\Subversion\bin;C:\Program Files (x86)\CMake\bin;C:\gnu\exiv2\trunk\contrib\cmake\msvc;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\gnu\exiv2\trunk\contrib\cmake\msvc;c:\Users\rmills\com;c:\Users\rmills\com\Subversion;c:\cygwin64\home\rmills\bin;c:\cygwin64\bin;c:\cygwin64\usr\sbin;C:\Users\rmills\AppData\Roaming\Python\Scripts

And now, I can build expat and zlib in the usual way. However you have to set --prefix=/cygdrive/c/MinGW/msys/1.0/localto have them built into you local directory. And now you can build exiv2 as follows:

c:\Users\rmills\gnu\exiv2\trunk>bash -c "./configure --prefix=/cygdrive/c/MinGW/msys/1.0/local/ --with-zlib=/cygdrive/c/MinGW/msys/1.0/local --with-expat=/cygdrive/c/MinGW/msys/1.0/local CXXFLAGS=-std=c++98"

Here's your local directory:

c:\Users\rmills\gnu\exiv2\trunk>dir c:\MinGW\msys\1.0\local\bin
 Volume in drive C has no label.
 Volume Serial Number is 0899-EF40

 Directory of c:\MinGW\msys\1.0\local\bin

09/06/2016  11:34 PM    <DIR>          .
09/06/2016  11:34 PM    <DIR>          ..
09/06/2016  10:30 PM           435,520 libexpat-1.dll
09/06/2016  10:30 PM           111,662 xmlwf
10/14/2014  10:33 AM           108,544 zlib.dll
10/14/2014  10:33 AM           108,544 zlib1.dll
               4 File(s)        764,270 bytes
               2 Dir(s)  21,416,603,648 bytes free

c:\Users\rmills\gnu\exiv2\trunk>dir c:\MinGW\msys\1.0\local\lib
 Volume in drive C has no label.
 Volume Serial Number is 0899-EF40

 Directory of c:\MinGW\msys\1.0\local\lib

09/06/2016  11:32 PM    <DIR>          .
09/06/2016  11:32 PM    <DIR>          ..
09/06/2016  11:27 PM         4,338,074 libexiv2.dll.a
09/06/2016  10:30 PM           549,498 libexpat.a
09/06/2016  10:30 PM            55,826 libexpat.dll.a
09/06/2016  10:30 PM               902 libexpat.la
09/06/2016  10:53 PM         1,675,852 libxmpsdk.a
09/06/2016  10:32 PM           124,160 libz.a
10/14/2014  10:33 AM            46,874 libz.dll.a
09/06/2016  10:30 PM    <DIR>          pkgconfig
               7 File(s)      6,791,186 bytes
               3 Dir(s)  21,416,603,648 bytes free

c:\Users\rmills\gnu\exiv2\trunk>

Now there's an issue. Something is going wrong in BasicIo.cpp that won't compile some windows special code. I think there must be an include file not available on the Qt Tool Chain that's provided by the TDM-GCC-64 tool chain. I also had a message I've never seen before about difficulty linking some of the XMP code to libexiv2.dll.a

When I get the DLL to link, it will go into the local/bin and your code will work!

C:\Users\rmills\Downloads\exifData>set PATH=c:\MinGW\msys\1.0\local\bin;%PATH%
C:\Users\rmills\Downloads\exifData>make -B CXXFLAGS=-std=c++98
....
C:\Users\rmills\Downloads\exifData>release\exifData.exe

So, I'm not done. However I am 100% confident of success.

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Sorry for the late reply!!

I have downloaded and installed only one version that is 0.25 so I am not sure how I can mess up with versions. I am really grateful to you for taking up this problem as yours and spending so much time on it in spite of your busy schedule. Thanks for your time. I will try working from my side and update you if I get anything working.

Thanks!!

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

I'm very surprised by all of this. However, I'm also very confident that it will work. I've gotta get on getting to feature complete v0.26. Then I'll look again at your stuff. Smile. Be Happy. Exiv2 is good stuff.

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 11 months ago

Sure and truly amazing stuff :)

RE: Integrating exiv2 with qt - Added by Robin Mills 11 months ago

It's working. All I had to do was RTFM (which I wrote). http://clanmills.com/exiv2/mingw.shtml

I enclose local.tar.gz and exifData.tar.gz. Have a look at the commandLineTool project in exifData. It has code from samples/exifprint.cpp. Worked first time. It's hard wired to dump c:\\temp\\Reagan.jpg (copied exiv2dir/test/data/Reagan.jpg)

You have to watch out for slippery stuff such as:

  1. Don't try to build exiv2 from DOS. Use the 32bit MinGW bash shell.
  2. Make sure you have the correct tool chain at the the start of your path: PATH="/C/Qt/Qt5.6.0/5.6/mingw49_32/bin:/C/Qt/Qt5.6.0/Tools/mingw492_32/bin:/c/MinGW/bin:/usr/bin:/usr/local/bin:."
  3. To link the samples: PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
  4. When building zlib: set INCLUDE_PATH, LIBRARY_PATH and BINARY_PATH to point to /c/MinGW/msys/1.0/local/include (or lib or bin)
  5. When building zlib: build a shared zlib make -f win32/Makefile.gcc SHARED_MODE=1
  6. Use the trunk. I fixed a couple of things today to enable the code to compile with Qt 5.6/mingw492_32
  7. Use the build flag CXXFLAGS=-std=c++98 (QMAKE_CXXFLAGS = -std=c++98 in .pro file) to silence GCC complaining about C++11 deprecated classes (AutoPtr)

////

It has been interesting to work on this. I think it's taken about 12 hours in total. I've easily doubled my knowledge and understanding of MinGW. It's my least favourite build environment. I've learned a lot of (boring) stuff while dealing with this.

Now I have to get on with getting Exiv2 to v0.26 feature complete.

local.tar.gz (9.69 MB)

exifData.tar.gz (258 KB)

RE: Integrating exiv2 with qt - Added by Robin Mills 10 months ago

I've put effort into MinGW/32/Qt and added a contrib/Qt/commandLineTool project and code. I've tested it on recent builds and I am confident that it works as documented. r4519

I've upgraded the buildserver to build/test/publish a daily mingw/32 build which is built with Qt5.6.0 tools (GCC 4.9.2). http://exiv2.dyndns.org:8080/userContent/builds/

54 -32- /home/rmills> which gcc
/c/Qt/Qt5.6.0/Tools/mingw492_32/bin/gcc.exe
55 -32- /home/rmills> gcc --version
gcc.exe (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

56 -32- /home/rmills>
The daily build includes:

  1. Documentation (ReadMe.txt and man pages)
  2. Built binaries of libraries for exiv2, expat and zlib
  3. Built binaries of DLLs for exiv2, expat and zlib
  4. Include files for exiv2, expat and zlib
  5. Built binary of exiv2.exe and all our sample programs
  6. Our sample code
  7. the Qt/commandLineTool project code

I hope you find those useful and that they work as documented. Feedback appreciated.

RE: Integrating exiv2 with qt - Added by SAITEJA Tallam 10 months ago

Hello Robin,

This will be really very useful. I have been successfully using Exiv2 through msys terminal (and it has been really useful in geo-tagging thousands of images) but I have not tasted success yet in using it with Qt. So I have tried checking (the libs from the link you sent and also the libs compiled on my system) if I have all the dependencies with dependencywalker and I get many errors. I am attaching the dependencywalker image for your review.

Thanks!!

RE: Integrating exiv2 with qt - Added by Robin Mills 10 months ago

I had a walk-through all of this stuff on Skype with Sai. We got it to work of course. We discovered some 'gotchas' concerning Qt/MinGW. I updated contrib/Qt appropriately. r4527

I'm going to remove Sai's attachments as they have no use for future visitors to this discussion.

(1-24/24)

Redmine Appliance - Powered by TurnKey Linux