Hello!
I need to make a .so or .a library and different headers, one of them to be shared with users to compile my main program (and link, in the code, processmatinlibrary_pub.h) and other to use in definitions and separated to the main code (processmatinlibrary.h).
When I use the public header (whitout some private definitions of methods), some times, depending on the structure of my program, I get segmentation faults or opencv assertions, below I paste my code, it could be dowloaded from https://github.com/eld1e6o/TestErrorOnLibrary
Here is my code and some comments
Files to create my main program, that uses functions on my library
This is the main function, I use it to check the library with public header I get some segmentation faults depending on the structure of my program I can force errors commenting #defines
#define _MAKE_ASSERT_OPENCV 1
#define _MAKE_SEGFAULT_ 1
*If I change the public header to the private header, I have not problems:
#include "processmatinlibrary.h" it works but the headers are not cshared
Instead of
#include "processmatinlibrary_pub.h"
It seems that is a stack problem and I need to define the library or the headers in the right way
Main.cpp
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include "processmatinlibrary_pub.h" //If I change this header to #include "processmatinlibrary.h" it works but the headers are not cshared
using namespace std;
using namespace cv;
#define _MAKE_ASSERT_OPENCV 1
//#define _MAKE_SEGFAULT_ 1
void testEmpty(cv::Mat test_img, std::string msg)
{
cout << "* Check empty " << msg ;
if(test_img.empty())
{
cout << ": Image is Empty " << endl;
exit(1);
}
else cout << ": Image is not empty " << endl;
}
int main(int argc, char* argv[])
{
// Classify and get probabilities
Mat test_img = imread(argv[1], CV_LOAD_IMAGE_COLOR);
testEmpty(test_img, "After load image");
cv::resize(test_img, test_img, cv::Size(256, 256));
cout << " After resize " << endl;
testEmpty(test_img, "Before initialize library ");
ProcessMatInLibrary matToLibrary;
#ifdef _MAKE_SEGFAULT_
return 0; // If I comment this line, I got a segmentation fault: Segmentation Fault (`core' generated)
#endif
testEmpty(test_img, "After initialize library ");
bool b = matToLibrary.flip(test_img);
testEmpty(test_img, "After use function in library ");
cout << "In main " << endl;
/*
* If I define _MAKE_ASSERT_OPENCV, I got errors
OpenCV(3.4.1) Error: Assertion failed (0 <= _dims && _dims <= 32) in setSize, file /home/diego/Code/opencv/modules/core/src/matrix.cpp, line 209
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(3.4.1) /home/diego/Code/opencv/modules/core/src/matrix.cpp:209: error: (-215) 0 <= _dims && _dims <= 32 in function setSize
*/
#ifndef _MAKE_ASSERT_OPENCV
imshow("Test before close", test_img); //If i comment this two lines, I got segmentation faults (OpenCV exception)
waitKey(0);
#endif
}
processmathlibrary_pub.h
This is my public header, used to define functions as publics
#ifndef PROCESSMATINLIBRARY_H
#define PROCESSMATINLIBRARY_H
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
class ProcessMatInLibrary
{
public:
ProcessMatInLibrary();
bool flip(cv::Mat image);
bool myTest(cv::Mat one);
};
#endif // PROCESSMATINLIBRARY_H
Files to create my library
processmathinlibrary.cpp
#include "processmatinlibrary.h"
using namespace std;
using namespace cv;
#include <iostream>
ProcessMatInLibrary::ProcessMatInLibrary()
{
cout << "Initialized " << endl;
}
bool ProcessMatInLibrary::flip(cv::Mat image)
{
cout << "** Inside Library: " << endl;
if(image.empty())
{
cout << " Image is empty" << endl;
return false;
}
cout << " Image is not empty " << endl;
// return false;
Mat image2;
cv::flip(image, image2, 0);
imshow("Image in library", image);
imshow("Image2 in library", image2);
waitKey(0);
cout << "Inside Library: Image is not empty" << endl;
return true;
}
bool ProcessMatInLibrary::myTest(cv::Mat one)
{
one.copyTo(_img);
}
processmathlibrary.h
This is my private header, used to compile my library, it only differs on private declarations
#ifndef PROCESSMATINLIBRARY_LIB_H
#define PROCESSMATINLIBRARY_LIB_H
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
class ProcessMatInLibrary
{
public:
ProcessMatInLibrary();
bool flip(cv::Mat image);
bool myTest(cv::Mat one);
private:
cv::Mat _img;
};
#endif // PROCESSMATINLIBRARY_LIB_H
How to compile all of this
CMakeLists.txt
Note that I have defined other PATH for OpenCV library, maybe there is an error to compile in the default PATH, I cannot check that find_package(OpenCV REQUIRED) is working
cmake_minimum_required(VERSION 2.8.12)
project(test_pub_priv)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -std=c++11")
#set(OpenCV_INCLUDE_DIRS "./include/")
find_package(OpenCV REQUIRED)
message(" ** Test with public private libraries ** ")
include_directories(${OpenCV_INCLUDE_DIRS})
aux_source_directory(./src SRC_LIST)
include_directories(./hpp SRC_LIST)
FILE(GLOB_RECURSE LibFiles "./hpp/*.h")
add_custom_target(headers SOURCES ${LibFiles})
add_library(myFramework ${SRC_LIST} )
add_executable(test_pub_priv ./examples/Main.cpp)
target_link_libraries(test_pub_priv ${OpenCV_LIBS} myFramework)
My question and problem is: What is the right way to pass a cv::Mat as argument trough library with one private header to the library and other (public header) to be shared?
Complete code can be seen here:
https://github.com/eld1e6o/TestErrorOnLibrary
Thanks!