unique_ptr and OpenSSL's STACK_OF(X509)* - c++

I use some using statements and unique_ptr to work with OpenSSL, as suggested in another question. Without, code becomes really ugly and I am not so much a fan of goto statements.
So far I have changed my code as far as possible. Here are examples, what I use:
using BIO_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using X509_ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using PKCS7_ptr = std::unique_ptr<PKCS7, decltype(&::PKCS7_free)>;
...
BIO_ptr tbio(BIO_new_file(some_filename, "r"), ::BIO_free);
Now I have the need of a STACK_OF(X509) and I do not know, if this is also possible with unique_ptr. I am looking for something similar to below, but this is not working.
using STACK_OF_X509_ptr = std::unique_ptr<STACK_OF(X509), decltype(&::sk_X509_free)>;
I also tried the Functor:
struct StackX509Deleter {
void operator()(STACK_OF(X509) *ptr) {
sk_X509_free(ptr);
}
};
using STACK_OF_X509_ptr = std::unique_ptr<STACK_OF(X509), StackX509Deleter>;
STACK_OF_X509_ptr chain(loadIntermediate(cert.string()));
The compiler accepts this and the application runs. Just one question: In other unique_ptrs as shown above, I always had specified a second argument, so I bet I am missing something:
STACK_OF_X509_ptr chain(loadIntermediate(cert.string()), ??????);
How do I use C++ unique_ptr and OpenSSL's STACK_OF(X509)*?

I defined a regular function:
void stackOfX509Deleter(STACK_OF(X509) *ptr) {
sk_X509_free(ptr);
}
Then I use it in my code:
using STACK_OF_X509_ptr = std::unique_ptr<STACK_OF(X509),
decltype(&stackOfX509Deleter)>;
STACK_OF_X509_ptr chain(loadIntermediate(cert.string()),
stackOfX509Deleter);

Related

C++ barrier function cannot be assign (windows)

I wanted to create something simple like void Function(struct str) to calculate paralel in barriers sync, but seems to not be so simple, so I followed this:
https://learn.microsoft.com/en-us/windows/win32/procthread/creating-threads
and some other topics, but without success. Couldnt find a solution. Code is all in one file.
Any advise how to fix it? make it work?
Solved by std::thread rewrite
Note how when you cast lpParam to a dectectorData* you should cast like this: (detectorData*)lpParam not (detectorData)lpParam. (Note the * denoting a pointer.)
Since I am using C++, there is already std::thread class.
So my simple task can be done by this code:
void detAndComputeT(detectorData &data) {
Ptr<SIFT> detector = cv::SIFT::create();
detector->detectAndCompute(data.image, Mat(), data.keypoints, data.descriptors);
}
and
std::thread threads2[2];
detectorData dataImage1;
detectorData dataImage2;
dataImage1.image = image1_toCalc;
dataImage2.image = image2_toCalc;
threads2[0] = thread(detAndComputeT, std::ref(dataImage1));
threads2[1] = thread(detAndComputeT, std::ref(dataImage2));
threads2[0].join();
threads2[1].join();

bug in c++?-set_difference in c++ does not return std::copy

I have a code like below:
typedef std::set<std::string> set_of_strings;
set_of_strings s1, s2, result1;
some_func()
{
s1.insert("1-2");
s1.insert("1-1");
s1.insert("3-4");
s2.insert("1-2");
s2.insert("1-3");
s2.insert("3-4");
set_of_strings::iterator s1_begin = s1.begin();
set_of_strings::iterator s1_end = s1.end();
set_of_strings::iterator s2_begin = s2.begin();
set_of_strings::iterator s2_end = s2.end();
set_of_strings::iterator result_begin = result1.begin();
td::insert_iterator<set_of_strings> result_inserter = std::inserter(result1, result_begin);
set_difference(s1_begin, s1_end,s2_begin, s2_end,result_inserter); //This is the problem line
}
The compilation error that i get is overloading ambiguity std::copy(....
the problem is set_difference returns like
return copy(first1,last1,result);
Please check here for the algo rithm of set_difference.
set_difference returns like :
copy(..)
if it is std::copy there would not be any problem.
i tried with putting my statement inside a block like below:
{
using namespace std;
set_difference(s1_begin, s1_end,s2_begin, s2_end,result_inserter);
}
but this doesn't work.
I know that the problem is with the copy function which we have written for our own purpose and its used at many places.Here i want to use std::copy.
could anybody pls help.
If you've written your own copy function that the compiler can see in the same scope as std::copy and it's a possible candidate, then sure that would cause an ambiguity.
There's no magic flag you can set to make it use std::copy, but I think if you put your own copy in a namespace and don't using that namespace, the compiler won't be able to find it and fall back to std::copy. That said, I don't think I can understand a case where you would want to create an alternate copy that works for set iterators, and if you wrote a generic one it probably shouldn't be called copy because it'll cause no end of ambiguity errors like this one.

How can boost::bind does not match the signature provided but works fine?

My confuse is like this code:
#include "stdafx.h"
#include <boost/bind.hpp>
using namespace std;
void fool(std::string s)
{
std::cout<<s<<endl;
}
void fool2()
{
std::cout<<"test2 called\n"<<endl;
}
void fool3(std::string s1,std::string s2)
{
std::cout<<"test3 called\n"<<endl;
}
typedef boost::function<void(std::string)> myHandler;
void mywait(myHandler handler)
{
handler("hello my wait");
}
int main()
{
mywait(boost::bind(fool,_1)); //it works fine as expected.
mywait(boost::bind(fool2)); //how it works? fool2 doesnot match the signature of "boost::function<void(std::string)>"
//mywait(boost::bind(fool3,_1,_2)); //if fool2 works fine, why this not work?
return 0;
}
the follow link is the same question.
http://forums.opensuse.org/english/development/programming-scripting/441878-how-can-boost-bind-swallow-argument-member-function.html
i just read the article:
[How the Boost Bind Library Can Improve Your C++ Programs]
and the boost doc about bind
those just say it works,but i don't know why. i still confused.
sorry about my poor English.wish i explained clearly yet.
One of the neat things about Boost.Bind is exactly it's ability to "massage" a function into a slightly different signature.
For example, you can make your fool3 example work by explicitly giving a value for the second parameter:
mywait(boost::bind(fool3, _1, "extra parameter"));
// or even:
mywait(boost::bind(fool3, "extra parameter", _1));
Any parameters that are passed to the function which don't get used (by a _n) are simply ignored when the function is called.

Syntax for std::binary_function usage

I'm a newbie at using the STL Algorithms and am currently stuck on a syntax error. My overall goal of this is to filter the source list like you would using Linq in c#. There may be other ways to do this in C++, but I need to understand how to use algorithms.
My user-defined function object to use as my function adapter is
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
bool operator()(SOURCE_DATA * test, SOURCE_TYPE ref)const
{
if (ref == SOURCE_All)
return true;
return test->Value == ref;
}
};
And in my main program, I'm using as follows -
typedef std::list<SOURCE_DATA *> LIST;
LIST; *localList = new LIST;;
LIST* msg = GLOBAL_DATA->MessageList;
SOURCE_TYPE _filter_Msgs_Source = SOURCE_TYPE::SOURCE_All;
std::remove_copy(msg->begin(), msg->end(), localList->begin(),
std::bind1st(is_Selected_Source<SOURCE_DATA*, SOURCE_TYPE>(), _filter_Msgs_Source));
What I'm getting the following error in Rad Studio 2010. The error means "Your source file used a typedef symbol where a variable should appear in an expression. "
"E2108 Improper use of typedef 'is_Selected_Source'"
Edit -
After doing more experimentation in VS2010, which has better compiler diagnostics, I found the problem is that the definition of remove_copy only allows uniary functions. I change the function to uniary and got it to work.
(This is only relevant if you didn't accidentally omit some of your code from the question, and may not address the exact problem you're having)
You're using is_Selected_Source as a template even though you didn't define it as one. The last line in the 2nd code snippet should read std::bind1st(is_Selected_Source()...
Or perhaps you did want to use it as a template, in which case you need to add a template declaration to the struct.
template<typename SOURCE_DATA, typename SOURCE_TYPE>
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
// ...
};
At a guess (though it's only a guess) the problem is that std::remove_copy expects a value, but you're supplying a predicate. To use a predicate, you want to use std::remove_copy_if (and then you'll want to heed #Cogwheel's answer).
I'd also note that:
LIST; *localList = new LIST;;
Looks wrong -- I'd guess you intended:
LIST *locallist = new LIST;
instead.

Possible to have C++ anonymous functions with boost?

I'm trying to solve a problem that anonymous functions make much, much easier, and was wondering if this was possible in c++.
What I would like to do is (essentially)
template<typename T>
T DoSomething(T one, function<T(T)> dosomething)
{
return one + dosomething(5);
}
void GetMyVal(...)
{
DoSomething<int>(1, /*anonymous func here*/)
}
This example is very, very simplified for what I have to do. In C# I would do p => p*5. I know this is easy with C++0x, but I can't use that. I feel that I should be able to do it with either boost::lambda, or a compination of boost::bind and boost::function with placeholders, but I can't seem to get it to work. This may not be possible and thats also fine, but please answer if its not possible. Thanks.
EDIT:
Ok, it seems the simple case of an int works fine, what about a more complicated structure? So, lets try
struct NumHolder
{
int x;
}
template<typename T>
T DoSomething(T one, function<T(NumHolder)> dosomething)
{
NumHolder temp;
temp = 5
return one + dosomething(temp);
}
void GetMyVal(...)
{
DoSomething<int>(1, /*anonymous func here*/)
}
Here my C# expression would be along the lines of p => p.temp * 5. Is this possible to do in C++ with boost?
EDIT 2: OK, now I'm just curious :D How would I call a function within the lambda expression? So, if we have
int ChangeVal(int mult)
{
return mult*5;
}
struct NumHolder
{
int x;
}
template<typename T>
T DoSomething(T one, function<T(NumHolder)> dosomething)
{
NumHolder temp;
temp = 5
return one + dosomething(temp);
}
void GetMyVal(...)
{
DoSomething<int>(1, /*anonymous func here*/)
}
In C# I could call p => ChangeVal(p). What would the syntax be for this with the C++ lambda expressions?
As Anders notes in his answer, boost::lambda can be useful, but the code can become hard to read in some cases. It thus depends on what you want to do in your anonymous function.
For simple case like the p => p * 5 you mention in your question, it seems to me that using Lambda or Bind would be reasonable, though:
DoSomething(1, _1 * 5);
Edit:
Your second example hits one area where the syntax gets quickly verbose: Member (data or function) access. Because the "dot" operator can't be overloaded in C++, you have to use a bind expression to get the "x" from the argument:
DoSomething(1, bind(&NumHolder::x, _1) * 5);
or, with Boost.Lambda, use the overloaded ->* operator:
DoSomething(1, &_1->* &NumHolder::x * 5);
Edit 2:
OK, one last time :)
In your last question, you write that in C#, you'd write p => ChangeVal(p), but the code above shows a ChangeVal taking an int, not a NumHolder, so it's not clear what you mean.
Assuming that ChangeVal takes an int and that you want the anonymous function to do the equivalent of ChangeVal(the_arg.x), you'd write this with Boost.Lambda:
DoSomething(1, bind(&ChangeVal, &_1->*&NumHolder::x));
or this with Boost.Bind (works with Lambda too):
DoSomething(1, bind(&ChangeVal, bind(&NumHolder::x, _1));
No, it isn't possible to do in a simple way. boost::lambda can help, but in my opinion the code is so hard to read when using it so I would avoid it.
I think the equivalent to C# p=>p*5 would be _1*5, but I've only looked at it briefly so I'm not sure. For simple stuff it works, but as soon as you need control structures you will have to use another set of control structures which are functionally based, rather than imperative. I found this so different from normal C++ code that I decided for myself that it is not worth using it, because it makes the code so hard to read for others.
boost doesn't extend syntax of c++. there are no anonymous functions in c++.