我正在尝试编译一个相对简单的演示应用程序,该应用程序使用dlsym()
从库中动态加载函数,并且还包括一些OpenCV函数。 make
告诉我:
[100%] Linking CXX executable test
CMakeFiles/test.dir/test.cpp.o: In function `main':
test.cpp:(.text+0x2f8): undefined reference to `cv::imread(cv::String const&, int)'
test.cpp:(.text+0x3e5): undefined reference to `cv::imencode(cv::String const&, cv::_InputArray const&, std::vector<unsigned char, std::allocator<unsigned char> >&, std::vector<int, std::allocator<int> > const&)'
CMakeFiles/test.dir/test.cpp.o: In function `cv::String::String(char const*)':
test.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x4d): undefined reference to `cv::String::allocate(unsigned long)'
CMakeFiles/test.dir/test.cpp.o: In function `cv::String::~String()':
test.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
CMakeFiles/test.dir/test.cpp.o: In function `cv::Mat::~Mat()':
test.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
CMakeFiles/test.dir/test.cpp.o: In function `cv::Mat::release()':
test.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
CMakeFiles/test.dir/build.make:94: recipe for target 'test' failed
make[2]: *** [test] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/test.dir/all' failed
make[1]: *** [CMakeFiles/test.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
在致电rm -rf *;cmake -DMAKE_BUILD_TYPE=Release ..
之后,我的CMakeLists.txt
如下:
ADD_EXECUTABLE (test test.cpp)
TARGET_LINK_LIBRARIES(test
${Open_CV_LIBS}
#/usr/lib/libalpropencv.so.3
openalpr
pthread
dl
)
我的测试程序的源代码如下:
#include <alpr.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <ios>
#include <dlfcn.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#define DLSYM 1
int main (void)
{
void *alprhandle = NULL;
std::string alprlib = "/usr/lib/libalpropencv.so.3";
#ifdef DLSYM
typedef void*(*palpr_init_type)(const char*, const char*, const char*, const char*);
void*(*palpr_init) (const char*, const char*, const char*, const char*);
typedef int (*palpr_is_loaded_type)(void*);
int (*palpr_is_loaded) (void*);
typedef alpr::AlprResults (*palpr_recognize_type)(std::vector<char>);
alpr::AlprResults (*palpr_recognize) (std::vector<char>);
//open OpenALPR OpenCV library
alprhandle = dlopen(alprlib.c_str(), RTLD_NOW);
if (!alprhandle){
std::cerr << dlerror() << alprlib <<std::endl;
exit(0);
}
//find the address of functions
palpr_init = (palpr_init_type)dlsym(alprhandle, "openalpr_init");
if (!palpr_init)
std::cerr << "FATAL: Could not find openalpr_init " << dlerror() << std::endl;
palpr_is_loaded = (palpr_is_loaded_type)dlsym(alprhandle, "openalpr_is_loaded");
if (!palpr_is_loaded)
std::cerr << "FATAL: Could not find openalpr_is_loaded " << dlerror() << std::endl;
palpr_recognize = (palpr_recognize_type)dlsym(alprhandle, "recognize");
if (!palpr_recognize)
std::cerr << "FATAL: Could not find recognize " << dlerror() << std::endl;
#endif
std::string fname = "/path/to/aws/0000024867.jpg";
std::ifstream is;
std::ostringstream ss;
#ifdef DLSYM
void *myinst = NULL;
myinst = palpr_init("us", "/etc/openalpr/openalpr.conf",NULL,NULL);
#else
alpr::Alpr openalpr("us", "/etc/openalpr/openalpr.conf");
openalpr.setTopN(20);
#endif
#ifdef DLSYM
if (palpr_is_loaded(myinst) == false)
#else
if (openalpr.isLoaded() == false)
#endif
{
std::cerr << "Error loading OpenALPR" << std::endl;
return 1;
}
//is.open(fname.c_str(), std::ios::binary);
//ss << is.rdbuf();
const std::string& s = ss.str();
cv::Mat image = cv::imread(fname.c_str(), CV_LOAD_IMAGE_COLOR);
std::vector <unsigned char> buff;
std::vector <int>param = std::vector<int>(2);
param[0] = cv::IMWRITE_JPEG_QUALITY;
param[1] = 70;
imencode(".jpg",image,buff,param);
std::vector<char> vec(buff.begin(), buff.end());
#ifdef DLSYM
alpr::AlprResults results = palpr_recognize(vec);
#else
alpr::AlprResults results = openalpr.recognize(vec);
#endif
// Carefully observe the results. There may be multiple plates in an image,
// and each plate returns the top N candidates.
for (unsigned int i = 0; i < results.plates.size(); i++) {
alpr::AlprPlateResult plate = results.plates[i];
std::cout << "plate" << i << ": " << plate.topNPlates.size() << " results" << std::endl;
for (unsigned int k = 0; k < plate.topNPlates.size(); k++) {
alpr::AlprPlate candidate = plate.topNPlates[k];
std::cout << " - " << candidate.characters << "\t confidence: " <<
candidate.overall_confidence << std::endl;
}
}
return 0;
}