C++ barrier function cannot be assign (windows) - c++

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();

Related

How can I get macro name from CStyleCastExpr matcher in clang-tidy?

I using clang-tidy for a while and creating some own checks. But now I stuck in this issue. I have a cstyle cast expression from which I want to get a macro name as string.
#define H_KEY 5;
float *a;
a = (float *)H_KEY; // I want to print out "H_KEY" from this expression
So I registered a matcher like this
void PointersCastCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(cStyleCastExpr().bind("cStyleCastExpr"), this);
}
I'm able to catch every cstyle cast and get a subExpr from it like this.
const Expr * subExpr = cStyleCast->getSubExpr();
So the clang tidy now give me information that I have "int" type sub-expression which is correct but I don't know how can I get the name of it.
What I tried was dynamic cast to DeclRefExpr, but this not pass. Also tried dynamic cast to BuiltinType, then I want to get a declaration but with no luck.
So please help. I think this should not be difficult.
Thank you!
If someone run in this issue, I resolve it like this.
if (subExpr->getExprLoc().isMacroID()) {
SourceManager &SM = *Result.SourceManager;
LangOptions LangOpts = getLangOpts();
StringRef subExprText = Lexer::getSourceText(CharSourceRange::getTokenRange(subExpr->getSourceRange()), SM, LangOpts);}
Maybe there is better approach but this one fits my needs.

What is the reverse operation of "myType& var = *(myType*) addrVar;" (c++)

In a code I didn't write and I have to use, using OpenCV (but it could be anything) I come across something like :
void foo (long addrImage){
[...]
Mat& image = *(Mat*)addrImage;
[...]
}
I want to do the reverse operation : create an adress based on a Mat&, but I'm not sure I understand completely the trick used.
What would the line be ?
long addrImage = (long)&image

unique_ptr and OpenSSL's STACK_OF(X509)*

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);

C/C++ string memory allocation

I've just recently begun with C/C++ development on an embedded system (ARM - STM32F4 to be more specific) and I am now having almost classical problems of someone who isn't used to C or low level memory managment.
Basically I have a class MenuOption that inherits some field from some other class and basically looks like this:
...
char text[20];
...
void MenuOption::setText(const char* text1)
{
clearCurrent();
needsUpdate = true;
strncpy(text, text1, 20);
width = font->FontWidth*strlen(text);
}
The constructor for this class calls that setText method to store the text. This works fine if I use it like this inside a main function:
std::vector<MenuOption *> mainMenuOptions;
MenuOption* op1 = new MenuOption(13, 15, "Info", WHITE, BLACK);
op1->setSelected(true);
mainMenuOptions.push_back(op1);
But it fails when I want to use it like this:
std::vector<MenuOption *> options;
for (int i = 0; i < things.size(); i++)
{
Thing *th = things[i];
... do some stuff with th ...
MenuOption* op = new MenuOption(190, 38+25*i, "test", WHITE, BLACK);
options.push_back(op);
}
This fails (debugger sort of stalls) at the MenuOption* op ... line. Now I am guessing that this isn't something that I should be doing. But I can't seem to find a working solution.
EDIT:
To answer everyones questions. This does in fact compile with a C++ compiler. GCC using C++11 dialect.
There is a reason why I am using C strings instead of std::string. I am using a few C libraries that need C strings. And whenever I tried to convert that string into a C string inside a FreeRTOS task the thing would fail. The same problem as now actually.
No other breakpoint inside the task will trigger after it reaches that constructor line. I can't step in or skip a line or anything like that at that line. I have a feeling it gets caught by a hard_fault interrupt handler. Other tasks would continue to run. That's the problem. There are no errors or anything that would point me to the cause. The same problem was when I was using std::string when I tried to create a new MenuOption inside a FreeRTOS task. The thing works if I remove the string from the constructor. So I am guessing that it has something to do with strings.
As for string length. I know that strings used here will not be longer than 15 characters. I used those 5 characters for pure "backup"-
As for the ... do some stuff with th ... that was just this: th->flag = true;. I didn't do anything more with it because of this problem.
The tip posted in the comments by Étienne was actually what lead me to the answer. More specifically I found this: http://www.freertos.org/FreeRTOS_Support_Forum_Archive/October_2013/freertos_Using_C_std_vector_in_task_93928e86j.html
void *operator new(size_t size)
{
void *p;
if(uxTaskGetNumberOfTasks())
p=pvPortMalloc(size);
else
p=malloc(size);
return p;
}
void operator delete(void *p)
{
if(uxTaskGetNumberOfTasks())
vPortFree( p );
else
free( p );
p = NULL;
}

c++ - Creating custom events at runtime

I'm creating a 2D RPG game engine in C++ with Allegro. I've reached the point in which i need to implement a scripting system. So, my poblem is this one:
I have a struct called Event. Inside this struct there is a function pointer, which points to the function that i want to execute when the event is fired. So, here's an example:
struct Event {
//...
void (*func)(Player*, void*);
//...
}
Now, to create an event i have this function:
Event* Events::register_event_source(int x, int y, std::string name, Player* player, void (*func)(Player*, void*));
So, to use it i just need to create a function with this signature:
void test_event(Player* p, void* data)
{
//Do something cool here
}
and then register an event source, giving the address to that function:
//...
Player* player = new Player(0, 0);
//...
Event* evt = Events::register_event_source(10, 10, "test event", player, &test_event);
//Eventually set some data for the event
evt->set_data(new std::string("Just some test data"));
In this way, when the player goes over the assigned spot (in this case x = 10, y = 10) the event will fire, executing any code in the test_event function.
Now, my question is: is it possible to do, or at least to get close to, this process at runtime?? ...i would need to create the function (in this case "test_event") at runtime, but i did some research, and i think what i understood is that it is not really possible to create functions at runtime.
So, which approach should i go for?? ...I know it is an abstract question...but i really don't know how to approach this problem.
Thanks in advice for any help! and sorry for my bad explaining abilities...English is not my language!
If I understand correctly what you are trying to express, you are writing a scripting engine that interprets some logics built at run-time into a string, and this should determine what to do on Player and data. If so, I can imagine you should have a function like
void InterpretScriptCode(Player* p, void* data, string const& code)
or something equivalent that interprets and execute the logics described in code on p and data.
Then, you can use std::bind and std::function to encapsulate a call to your scripting engine:
// Header <functional> needs to be included, and a proper "using namespace"
// directive must be present for bringing placeholders _1 and _2 into scope
std::function<void(Player*, void*)> fxn = std::bind(
&InterpretScriptCode,
_1,
_2,
"int x = 0; ... blah blah" // this should be your run-time generated script
);
And pass fxn in input to your register_event_source() function.
Btw, you might be interested in using Boost.Signals/Boost.Signals2 for realizing event registration/handling.
If you are not using C++11, you can use boost::bind and boost::function instead of std::bind and std::function.