RcppParallel using References in workers - rcpp

I have been experiment with using references for speed improvements. The (not working) trivial example below, probably won't see any improvements. However, I think by not copying the data into a separate (cost) function, should save some time for a non trivial example.
As for now I have the example in an R-project as three c++ files:
header
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
void myfuncA(arma::rowvec &vec_in, arma::colvec& data){
vec_in.at(1) = vec_in.at(0)*arma::accu(data);
}
struct PARALLEL_WORKER : RcppParallel::Worker{
arma::mat &input_output;
const arma::colvec &data_in;
PARALLEL_WORKER(arma::mat &input_output, const arma::colvec &data_in);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
Function
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::mat Parallelfunc(int Len_in, const arma::colvec data_in){
arma::mat input(Len_in, 2, arma::fill::zeros);
for(unsigned int i = 0; i < Len_in; i ++){
input.at(i, 0) =i;
}
ExampleInternal::PARALLEL_WORKER worker(input, data_in);
parallelFor(0, Len_in, worker);
return input;
}
Parallel Worker
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace RcppParallel;
using namespace ExampleInternal;
namespace ExampleInternal{
PARALLEL_WORKER::PARALLEL_WORKER(arma::mat &input_output, const arma::colvec &data_in) : input_output(input_output), data_in(data_in) {}
void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
for(unsigned int k = begin; k < end; k ++){
ExampleInternal::myfuncA(input_output.row(k), data_in);
}
}
}

Related

Adding function pointers to Parallel Worker

Building off the example here Parallel Worker in namespace, I would like to employ function pointers with the Parallel Worker.
The code below produces an error along the lines of: "cannot initialize a new value of type (**) with a return value of (*)"
ExampleInternal.h
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
#include <memory>
double myfuncA(arma::vec vec_in);
double myfuncB(arma::vec vec_in);
typedef double (*funcPtr)(arma::vec);
std::shared_ptr<funcPtr> selectfunc(std::string abc){
if(abc == "A"){
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncA));
}else {
return std::make_shared<funcPtr>(new funcPtr(&ExampleInternal::myfuncB));
}
}
struct PARALLEL_WORKER : RcppParallel::Worker{
const arma::vec &input;
std::shared_ptr<funcPtr> &Ptr;
arma::vec &output;
PARALLEL_WORKER( const arma::vec &input, std::shared_ptr<funcPtr> &Ptr, arma::vec &output);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
myfuncA.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncA(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
} // Close namespace
myfuncB.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace arma;
namespace ExampleInternal{
double myfuncB(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])*Len;
}
} // Close namespace
Parallel_worker.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <random>
#include <memory>
#include "ExampleInternal.h"
using namespace RcppParallel;
using namespace ExampleInternal;
namespace ExampleInternal{
PARALLEL_WORKER::PARALLEL_WORKER(const arma::vec &input, std::shared_ptr<ExampleInternal::funcPtr> &Ptr, arma::vec &output) : input(input), Ptr(Ptr), output(output) {}
void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = Ptr(index);
}
}
} //Close Namespace
Parallel_func.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <memory>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in, std::string func_letter){
std::shared_ptr<funcPtr> df = ExampleInternal::selectfunc(func_letter);
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
ExampleInternal::PARALLEL_WORKER parallel_woker(input, df, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
You may also need a makevars to specify c++11, on mac:
CXX_STD = CXX11
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")
Ok this works. And the shared_ptr is not needed.
ExampleInternal.h
#ifndef ExampleInternal_H
#define ExampleInternal_H
namespace ExampleInternal{
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <Rcpp.h>
#include <memory>
double myfuncA(arma::vec vec_in);
double myfuncB(arma::vec vec_in);
typedef double (*funcPtr)(arma::vec);
ExampleInternal::funcPtr func_select(int abc);
struct PARALLEL_WORKER : RcppParallel::Worker{
const arma::vec &input;
ExampleInternal::funcPtr &Ptr;
arma::vec &output;
PARALLEL_WORKER( const arma::vec &input, ExampleInternal::funcPtr &Ptr, arma::vec &output);
void operator()(std::size_t begin, std::size_t end);
};
}
#endif
func_select.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
namespace ExampleInternal{
ExampleInternal::funcPtr func_select(int abc){
ExampleInternal::funcPtr df;
if(abc == 1){
df = &ExampleInternal::myfuncA;
}else{
df = &ExampleInternal::myfuncB;
}
return df;
}
} //close namespace
Parallel_func.cpp
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <memory>
#include "ExampleInternal.h"
using namespace ExampleInternal;
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in, int func_num){
ExampleInternal::funcPtr point = ExampleInternal::func_select(func_num);
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
ExampleInternal::PARALLEL_WORKER parallel_woker(input, point, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}

Calling 'mypackage' function within public worker

I know the problem I have is a thread-safety issue. As the code I have now will execute with 'seThreadOptions(1)'. My question is what would be a good practice to overcome this.
I know this: Threadsafe function pointer with Rcpp and RcppParallel via std::shared_ptr Will come into play somehow. And I have also been thinking/playing around with making the internal function part of the structure for the parallel worker. Realistically, I am calling two internal functions and I would like one to be variable and the other to be constant, this tends me to think that i will need 2 solutions.
The error is that the R session, in rstudio, crashes.
Two things of note here:
1. if I 'setThreadOptions(1)' this runs fine.
2. if I move 'myfunc' into the main cpp file and make the call simply 'myfunc' this also runs fine.
Here is a detailed example:
First cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(cpp)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
Second,cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(ParallelExample)]]
#include "RcppArmadillo.h"
#include "RcppParallel.h"
#include "ParallelExample.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ParallelExample::myfunc(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}
Makevars, as I am using a macintosh:
CXX_STD = CXX11
PKG_CXXFLAGS += -I../inst/include
And Namespace:
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
importFrom(RcppParallel,RcppParallelLibs)
useDynLib(ParallelExample, .registration = TRUE)
export(Parallelfunc)
When you call ParallelExample::myfunc, you are calling a function defined in inst/include/ParallelExample_RcppExport.h, which uses the R API. This is something one must not do in a parallel context. I see two possibilities:
Convert myfunc to header-only and include it in int/include/ParallelExample.h.
If the second cpp file is within the same package, put a suitable declaration for myfunc into src/first.h, include that file in both src/first.cpp and src/second.cpp, and call myfunc instead of ParallelExample::myfunc. After all, it is not necessary to register a function with R if you only want to call it within the same package. Registring with R is for functions that are called from the outside.
In some ways this kinda defeats the purpose of the built in interface cpp feature of Rcpp.
First, cpp saved as 'ExampleInternal.h':
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
namespace ExampleInternal
{
double myfunc3(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
}
and second:
#include "ParallelExample.h"
#include "ExampleInternal.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace ExampleInternal;
using namespace std;
struct PARALLEL_WORKER : public Worker{
const arma::vec &input;
arma::vec &output;
PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
void operator()(std::size_t begin, std::size_t end){
std::mt19937 engine(1);
// Create a loop that runs through a selected section of the total Boot_reps
for( int k = begin; k < end; k ++){
engine.seed(k);
arma::vec index = input;
std::shuffle( index.begin(), index.end(), engine);
output[k] = ExampleInternal::myfunc3(index);
}
}
};
// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){
arma::vec input = arma::regspace(0, 500);
arma::vec output(Len_in);
PARALLEL_WORKER parallel_woker(input, output);
parallelFor( 0, Len_in, parallel_woker);
return output;
}

C++ thread and mutex and condition variable

findsmallest common multiple of 10-million numbers in the queue does not exceed 10,000
I killed 2 days to sort out but I just do not understand! please help me
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
#include <cmath>
#include <map>
#include <cstdlib>
#include <fstream>
#include <ctime>
using namespace std;
int main()
{
std::map <int, int> NOK;
map<int, int> snok;
std::queue<int> oche;
std::mutex m;
std::condition_variable cond_var;
bool done = false;
bool notified = false;
std::thread filev([&]() {
//std::unique_lock<std::mutex> lock(m);
ifstream in; // Поток in будем использовать для чтения
int ch;
in.open("/home/akrasikov/prog/output.txt");
while(!in.eof()){
if (oche.size()>9999){
std::this_thread::sleep_for(std::chrono::milliseconds(3));
std::unique_lock<std::mutex> lock(m);
} else {
in>>ch;
oche.push(ch);
}
}
notified = true;
cond_var.notify_one();
done = true;
cond_var.notify_one();
});
std::thread nok([&]() {
std::unique_lock<std::mutex> lock(m);
while (!done) {
while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
while (!oche.empty()) {
ch=oche.front();
oche.pop();
int j=2;
while (j < sqrt((double)ch)+1){
int s=0;
while(!(ch%j)){
s++;
ch/=j;
}
if (s > 0 && NOK[j] < s){
NOK[j] = s;
}
j++;
}
if (NOK[ch] == 0) NOK[ch]++;
}
long int su=1;
int temp=-1;
int step=0;
int sa=1;
std::cout << " NOK= ";
for (std::map<int, int>::iterator it=NOK.begin(); it!=NOK.end(); it++){
for (int i=0; i<it->second; i++){
su*=it->first;
sa=it->first;
if (temp<sa && sa >1){
temp=sa;
step=1;
} else {
if(sa>1)
step++;
}
}
cout<< temp << "^"<< step << " * " ;
}
std::cout << "su = " << su << '\n';
}
notified = false;
});
filev.join();
nok.join();
}
This program does not work! how come? what's wrong? it just starts and hangs, but if you do not delete is code
if (oche.size()>9999){
std::this_thread::sleep_for(std::chrono::milliseconds(3));
std::unique_lock<std::mutex> lock(m);
} else {
and
while (!done) {
while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
everything works help plz
From what I understand of your problem, you have 3 problems
Conpute the least common multiple for a list of 1M elements
You want to have one thread that produces the elements and one that consumes it. They transfer it through a buffer (a queue in your case)
Your queue cannot exceed 10K elements
In my implementation I m generating the numbers randomly and using condition variables to coordinate between the threads.
Note that the LCM is associative so you can compute it recursively, not matter what the order is.
Here is the code but please DO NOT POST DIRTY CODE LIKE YOU DID NEXT TIME OR EVERYONE will kick you out.
Here is the code
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
#include <cmath>
#include <map>
#include <cstdlib>
#include <fstream>
#include <ctime>
#include <atomic>
#include <random>
using namespace std;
std::mutex mutRandom;//use for multithreading for random variables
int getNextRandom()
{
std::lock_guard<std::mutex> lock(mutRandom);
// C++11 Random number generator
std::mt19937 eng (time(NULL)); // Mersenne Twister generator with a different seed at each run
std::uniform_int_distribution<int> dist (1, 1000000);
return dist(eng);
}
//thread coordination
std::mutex mut;
std::queue<int> data_queue;
std::condition_variable data_cond;
std::atomic<int> nbData=0;
std::atomic<int> currLCM=1;//current LCM
const unsigned int nbMaxData=100000;
const unsigned int queueMaxSize=10000;
//Arithmetic function, nothing to do with threads
//greatest common divider
int gcd(int a, int b)
{
for (;;)
{
if (a == 0) return b;
b %= a;
if (b == 0) return a;
a %= b;
}
}
//least common multiple
int lcm(int a, int b)
{
int temp = gcd(a, b);
return temp ? (a / temp * b) : 0;
}
/// Thread related part
//for producing the data
void produceData()
{
while (nbData<nbMaxData)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk,[]{
return data_queue.size()<queueMaxSize;
});
cout<<nbData<<endl;
++nbData;
data_queue.push(getNextRandom());
data_cond.notify_one();
lk.unlock();
}
cout<<"Producer done \n";
}
//for consuming the data
void consumeData()
{
while (nbData<nbMaxData)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk,[]{
return !data_queue.empty();
});
int currData=data_queue.front();
data_queue.pop();
lk.unlock();
currLCM = lcm(currLCM,currData);
}
cout<<"Consumer done \n";
}
int main()
{
std::thread thProduce(&produceData);
std::thread thConsume(&consumeData);
thProduce.join();//to wait for the producing thread to finish before the program closes
thConsume.join();//same thing for the consuming one
return 0;
}
Hope that helps,

C++ Windows Form Application: Attempted to read or write protected memory (unmanaged class)

I'm trying to use Boost library in my C++ Windows Form Application and I always get an exception:
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I'm using Visual Studio 2012 and Boost version 1.57.0. Previously I used Boost version 1.56.0 but upgrading didn't solve my issue.
Here are the code:
MyForm.cpp
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
void main(cli::array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
TestUnmanaged::MyForm form;
Application::Run(%form);
}
MyForm.h
#pragma once
#include <iostream>
#include <map>
#include <sstream>
#include <cassert>
#include <stdio.h>
#include "ExternalProfileManager.h"
#define DEFAULT_PROFILE_NAME "profile.bin"
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "lib/edk.lib")
namespace TestUnmanaged {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
ExternalProfileManager profileManager;
/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
profileManager.load(DEFAULT_PROFILE_NAME);
std::vector<std::string> profileList;
profileManager.listProfile(profileList);
}
ExternalProfileManager.h
#ifndef EXTERNAL_PROFILE_MANAGER_H
#define EXTERNAL_PROFILE_MANAGER_H
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/base_object.hpp>
class ExternalProfileManager
{
ExternalProfileManager(const ExternalProfileManager&) {};
ExternalProfileManager& operator = (const ExternalProfileManager&) {};
protected:
std::map<std::string, std::string > _profiles;
typedef std::map<std::string, std::string >::iterator profileItr_t;
// Boost serialization support
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int /*file version */)
{
ar & _profiles;
}
public:
ExternalProfileManager();
virtual ~ExternalProfileManager();
virtual bool save(const std::string& location);
virtual bool load(const std::string& location);
virtual bool insertProfile(const std::string& name, const unsigned char* profileBuf, unsigned int bufSize);
virtual bool listProfile(std::vector<std::string>& profiles);
};
//BOOST_CLASS_EXPORT(ExternalProfileManager);
//BOOST_CLASS_TRACKING(ExternalProfileManager, boost::serialization::track_never);
#endif // EXTERNAL_PROFILE_MANAGER_H
ExternalProfileManager.cpp
#include <fstream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/regex.hpp>
#pragma warning(push)
#pragma warning(disable : 4267) // "conversion from size_t to unsigned int"
#pragma warning(disable : 4996)
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#pragma warning(pop)
#include "ExternalProfileManager.h"
using namespace std;
namespace fs = boost::filesystem;
ExternalProfileManager::ExternalProfileManager()
{
}
ExternalProfileManager::~ExternalProfileManager()
{
}
bool ExternalProfileManager::save(const string& location)
{
ofstream ofs(location.c_str(), ios_base::binary);
if ( !ofs.is_open() ) return false;
try {
boost::archive::binary_oarchive oa(ofs);
oa << *this;
}
catch (boost::archive::archive_exception& )
{
return false;
}
return true;
}
bool ExternalProfileManager::load(const string& location)
{
ifstream ifs(location.c_str(), ios_base::binary);
if ( !ifs.is_open() ) return false;
try {
boost::archive::binary_iarchive ia(ifs);
ia >> *this;
}
catch (boost::archive::archive_exception& )
{
return false;
}
return true;
}
bool ExternalProfileManager::insertProfile(const string& name, const unsigned char* profileBuf, unsigned int bufSize)
{
assert(profileBuf);
// Replace our stored bytes with the contents of the buffer passed by the caller
string bytesIn(profileBuf, profileBuf+bufSize);
_profiles[name] = bytesIn;
return true;
}
bool ExternalProfileManager::listProfile(vector<string>& profiles)
{
profiles.clear();
for ( profileItr_t itr = _profiles.begin(); itr != _profiles.end(); ++itr ) {
profiles.push_back(itr->first);
}
return true;
}
The error occurred in ia >> *this; in ExternalProfileManager::load (thrown in file basic_archive.cpp). So calling profileManager.load(DEFAULT_PROFILE_NAME); from form constructor will trigger the exception.
Calling save will also trigger the same exception but other functions which have no this will work fine.
I tried creating a console application in VS 2012 and call ExternalProfileManager.h and it works perfectly (including save, load, and any other function). Here are the simple console application I created to test it:
Console.cpp
#include <iostream>
#include <map>
#include <sstream>
#include <cassert>
#include <stdio.h>
#include "ExternalProfileManager.h"
#define DEFAULT_PROFILE_NAME "profile.bin"
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "lib/edk.lib")
ExternalProfileManager profileManager;
int main(int argc, char** argv) {
profileManager.load(DEFAULT_PROFILE_NAME);
std::vector<std::string> profileList;
profileManager.listProfile(profileList);
std::cout << "Available profiles:" << std::endl;
for (size_t i=0; i < profileList.size(); i++) {
std::cout << i+1 << ". " << profileList.at(i);
if (i+1 < profileList.size()) {
std::cout << std::endl;
}
}
return true;
}
profile.bin is generated from calling save function in console application and contain serialized data generated by boost. I can provide the file if it is needed to solve this issue.
I have also tried to create a simple class wrapper but the exception still occurred.
WrapperExternalProfileManager.h
#ifndef WRAPPER_EXTERNAL_PROFILE_MANAGER_H
#define WRAPPER_EXTERNAL_PROFILE_MANAGER_H
#include <string>
#include <vector>
class WrapperExternalProfileManager
{
WrapperExternalProfileManager(const WrapperExternalProfileManager&) {};
WrapperExternalProfileManager& operator = (const WrapperExternalProfileManager&) {};
public:
WrapperExternalProfileManager();
virtual ~WrapperExternalProfileManager();
virtual bool save(const std::string& location);
virtual bool load(const std::string& location);
virtual bool insertProfile(const std::string& name, const unsigned char* profileBuf, unsigned int bufSize);
virtual bool listProfile(std::vector<std::string>& profiles);
};
#endif
WrapperExternalProfileManager.cpp
#include "WrapperExternalProfileManager.h"
#include "ExternalProfileManager.h"
using namespace std;
ExternalProfileManager profileManager;
WrapperExternalProfileManager::WrapperExternalProfileManager()
{
std::cout<<"Constructor WrapperExternalProfileManager"<<std::endl;
}
WrapperExternalProfileManager::~WrapperExternalProfileManager()
{
}
bool WrapperExternalProfileManager::save(const string& location)
{
return profileManager.save(location);
}
bool WrapperExternalProfileManager::load(const string& location)
{
return profileManager.load(location);
}
bool WrapperExternalProfileManager::insertProfile(const string& name, const unsigned char* profileBuf, unsigned int bufSize)
{
return profileManager.insertProfile(name, profileBuf, bufSize);
}
bool WrapperExternalProfileManager::listProfile(vector<string>& profiles)
{
return profileManager.listProfile(profiles);
}
save and load still trigger the exception but other functions work perfectly.
Here are some property of the application which might be helpful:
Linker -> System -> SubSystem: Windows (/SUBSYSTEM:WINDOWS)
General -> Common Language Runtime Support: Common Language Runtime Support (/clr)
I know I have done something incorrectly but I don't know which part. Any suggestion to solve this issue would be appreciated.
Thanks in advance
You're going to have to find the source of your Undefined Behaviour (use static analysis tools, heap checking and divide and conquer).
I've just built your code on VS2013 RTM, using a ultra-simple C# console application as the driver:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var f = new TestUnmanaged.MyForm();
f.ShowDialog();
}
}
}
This JustWorks(TM).
I created a profile.bin with 100 random profiles of varying length:
#if 1
for (int i = 0; i < 100; ++i)
{
std::vector<uint8_t> buf;
std::generate_n(back_inserter(buf), rand() % 1024, rand);
insertProfile("profile" + std::to_string(i), buf.data(), buf.size());
}
save(location);
#endif
And they are deserialized just fine.
Good luck.
Download the full project here http://downloads.sehe.nl/stackoverflow/q27032092.zip in case you want to fiddle with it (compare the details?)

How to access many images from folder

I am trying to process many picture's at a time and then make all to equal size
Mat pic = imread ("C:\\Pick");
for (int i=0;i<10;i++)
{
imshow("mainwin" , pick);
resize (pick,re_pic,size(150,100));
}
Pick is a folder which contain 10 different picture's
You can get list of images in directory and then process them.
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
//----------------------------------------------------------------------
// Get list of files
// Usage:
// string ImagesDir=tmp+"C:\\Images\\*.jpg";
// vector<string> files=listFilesInDirectory(ImagesDir);
//----------------------------------------------------------------------
vector<string> listFilesInDirectory(string directoryName)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(directoryName.c_str(), &FindFileData);
vector<string> listFileNames;
listFileNames.push_back(FindFileData.cFileName);
while (FindNextFile(hFind, &FindFileData))
listFileNames.push_back(FindFileData.cFileName);
return listFileNames;
}
...
// somewhere in main
string YourImagesDirectory="C:\\Pick\\";
vector<string> files=listFilesInDirectory(YourImagesDirectory+"*.jpg");
for(int i=0;i<files.size();i++)
{
Mat img=imread(YourImagesDirectory+files[i]);
imshow("mainwin" , img);
...
}
...

Resources