I'm trying to build fully standalone DLL in C++ with Microsoft Visual Studio 2017. Generally I use c++ with OpenCV and LabVIEW extra libraries and everything was ok, until I try to run it on external machine in LabVIEW.
I build own environment for linking my Machine Vision methods as a real time applications for LabVIEW. My DLL analyse only one image/frame at once. Everything works perfectly until I starts to use my new method, which is based on Haar Cascade Classifier (HCC), which requires extra XML file with weights. I train my own HCC weights and they are saved as an XML file, which must be read by code during compilation. Unfortunately DLL requires path to this file on every machine, which makes work with it difficult. Is there any option to import this XML content permanently to the DLL? I don't want to give this path to the DLL every single time I run it. In the code below I paste some snippet of my problem. Before compilation I must give path to cascade XML file as HaarPathXML variable. I think this is the reason why my code crush on other machine - it doesn't see this path. Is there option for hard-code this file data during compilation?
// ========================
// === SOME HEADER CODE ===
// ========================
// === Dll entry point ===
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(hModule);
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// === Function to export as DLL ===
extern "C" __declspec(dllexport) char* PupilData(
const uint8_t *__arr[],
const uint16_t __img_rows,
const uint16_t __img_cols,
uint8_t __GB,
) // Describe inputs
{
// === Define the data ===
string HaarPathXML = "C:\\Users\\path_to_file\\cascade.xml";
// ====================================================================
// === SOME MAIN CODE, WHICH GIVES out VARIABLE WITH CALCULATED DATA ===
// ====================================================================
// === Change out string to char table and return it as an DLL output ===
char* C_pupil_data = new char[out.size() + 1];
copy(out.begin(), out.end(), C_pupil_data);
C_pupil_data[out.size()] = '\0';
return C_pupil_data;
}
I think that I can give the path as another variable and prepare LabVIEW code for this. But I'm looking for easier way to work with that. Furthermore - continuous reading of XML file might reduce frames per seconds of my code.
First time I will answer to my own question ;) According to one of the answers in SO, I made .h file, which contains XML content, but converted by hand (but only once) to string. This is how XML2Str.h looks:
#pragma once
#include <string>
static inline string StringXML()
{
string xml;
xml = "<\?xml version=\"1.0\"\?>\n";
xml += "<opencv_storage>\n";
xml += "<cascade>\n";
xml += ...
xml += "</opencv_storage>";
return xml
}
After this I call above method to obtain OpenCV String object and I use method FileStorage to read (not load) converted and Hard Coded XML.
#include "XML2Str.h"
CascadeClassifier cascade;
String HaarPathXML_h = StringXML();
FileStorage fs(HaarPathXML_h, FileStorage::MEMORY);
cascade.read(fs.getFirstTopLevelNode());
After those operations everythink works well in .exe and .dll files without extra XML files with models.