Newbie writing a C wrapper for Exiv2
Added by Clive McCarthy about 3 years ago
I'm not a C++ programmer so I'm writing a small wrapper to interface Exiv2 to my C code. It's is very simple but I just can't figure out the necessary methods to get the C++ data into my C data structures. It really is my ignorance of C++ but I'd appreciate some help! My wrapper looks like the following. You can see the erroneous lines near the end.
exiv2_wrapper.c (1.96 KB) exiv2_wrapper.c |
Replies (3)
RE: Newbie writing a C wrapper for Exiv2 - Added by Robin Mills about 3 years ago
You are going in the correct direction.
Here's what I would do with my favourite test file (which is only my web-site)
832 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $ bin/exiv2 -pa --grep date/i http://clanmills.com/Stonehenge.jpg Exif.Image.DateTime Ascii 20 2015:07:16 20:25:28 Exif.Photo.DateTimeOriginal Ascii 20 2015:07:16 15:38:54 Exif.Photo.DateTimeDigitized Ascii 20 2015:07:16 15:38:54 Exif.NikonWt.DateDisplayFormat Byte 1 Y/M/D Exif.GPSInfo.GPSDateStamp Ascii 11 2015:07:16 Xmp.xmp.ModifyDate XmpText 25 2015-07-16T20:25:28+01:00There's a sample program exifvalue that prints the value of an Exif tag:
833 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $ bin/exifvalue http://clanmills.com/Stonehenge.jpg Exif.Photo.DateTimeOriginal 2015:07:16 15:38:54 834 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $Let's write exifvalue in "C".
1) put main in main.c.
2) put the C++ magic in wrapper.cpp
3) the header file into wrapper.h
main.c
// ***************************************************************** -*- C -*- // main.c (samples/exifvalue.cpp written in C) #include "wrapper.h" #include <stdio.h> // To build: // g++ -std=c++98 main.c wrapper.cpp -I/usr/local/include -L/usr/local/lib -lexiv2 -o main // // To test: // ./main http://clanmills.com/Stonehenge.jpg Exif.Photo.DateTimeOriginal // 2015:07:16 15:38:54 // int main(int argc, const char* argv[]) { const char* prog = argv[0]; const char* path = argv[1]; const char* key = argv[2]; int rc = 0 ; if (argc != 3) { printf("Usage: %s path key\n",prog); rc = 1; } else { char buffer[100]; if ( getMetadata(path,key,buffer,sizeof(buffer)) ) { printf("%s\n",buffer); } else { printf("key %s not in %s\n",key,path); rc = 2; } } return rc; }
wrapper.h
#ifdef __cplusplus extern "C" { #endif int getMetadata(const char* path,const char* key,char* buffer,const int buffer_l); #ifdef __cplusplus } #endif
wrapper.cpp
// ***************************************************************** -*- C++ -*- // wrapper.cpp #include <exiv2/exiv2.hpp> #include "wrapper.h" extern "C" { int getMetadata(const char* path,const char* key,char* buffer,int buffer_l) { Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path); assert(image.get() != 0); image->readMetadata(); Exiv2::ExifData& exifData = image->exifData(); strcpy(buffer, exifData[key].toString().c_str()); return 1; } }
This was quickly written. I have not put exception handling and buffer overflow checks in wrapper.cpp
I'm really busy at the moment working on Exiv2 v0.27 RC1. If you want to discuss this in more detail, can I ask you to wait until next week. I will be happy to screen share with you if you need some one-to-one assistance.
RE: Newbie writing a C wrapper for Exiv2 [solved] - Added by Clive McCarthy about 3 years ago
My working code looks like this:
extern "C" { #include "common_header.h" #include "lip_image_processing.h" #include "lip_image_processing_internal.h" } void exiv2(const char *jpg_filename, IMAGE *jpg_image) { char data[256]; Exiv2::ExifData::const_iterator exif_data_ptr, begin, end; Exiv2::Image::AutoPtr image; image = Exiv2::ImageFactory::open(jpg_filename); if(!image.get()) { image_lib_program_error(__FILE__, __LINE__, __FUNC__, "can't read <%s>", jpg_filename); } image->readMetadata(); Exiv2::ExifData &exifData = image->exifData(); if(exifData.empty()) { image_lib_program_warning(__FILE__, __LINE__, __FUNC__, "Exif data is empty in file <%s>", strip_path_from_filename(jpg_filename)); return; } begin = exifData.begin(); end = exifData.end(); for(exif_data_ptr = begin; exif_data_ptr != end; exif_data_ptr++) { strncpy(data, exifData[exif_data_ptr->key()].toString().c_str(), 255); switch(exif_data_ptr->tag()) { case EXIF_CAMERA_MODEL_TAG: strncpy(jpg_image->CameraModel, data, CAMERA_MODEL_STRING_LENGTH); break; case EXIF_ORIENTATION_TAG: jpg_image->orientation = atoi(data); break; case EXIF_DATETIME_TAG: strncpy(jpg_image->DateTime, data, DATETIME_STRING_LENGTH); break; default: break; } } printf ( "%s\n\tcamera=\"%s\" datetime=\"%s\" orientation=%d\n", jpg_filename, jpg_image->CameraModel, jpg_image->DateTime, jpg_image->orientation ); }
working_exiv2.c (1.46 KB) working_exiv2.c |
RE: Newbie writing a C wrapper for Exiv2 - Added by Robin Mills about 3 years ago
I'm a little lost, here. I see you marked this "[Solved]", so I guess we're done. Thank you for using Exiv2.