In OpenCV I want to return the point position like Point(x,y) to the main() function that I click on the image in the mouse callback function . Is there anyway other than setting a global variable?
I don't want to write all the codes inside the on_mouse() function.
Thanks
to expand Safirs idea there, apart from a class or such, you could just pass in the point itself:
void on_mouse( int e, int x, int y, int d, void *ptr )
{
Point*p = (Point*)ptr;
p->x = x;
p->y = y;
}
Point p;
namedWindow("win");
setMouseCallback("win",on_mouse, (void*)(&p) );
// changed value of p will be accessible here
You can avoid using global variables by passing a pointer to your data as a parameter to setMouseCallback(). Agree with #berek, just wanted to show a full example below to avoid confusion about global variables.
using namespace cv;
void on_mouse( int e, int x, int y, int d, void *ptr )
{
Point*p = (Point*)ptr;
p->x = x;
p->y = y;
}
in main() {
Point p;
namedWindow("window");
Mat image = imread("someimage.jpg");
imshow(image);
//pass a pointer to `p` as parameter
setMouseCallback("window",on_mouse, &p );
// p will update with new mouse-click image coordinates
// whenever user clicks on the image window
}
No, this isn't possible, since the on_mouse() is a callback function. Here is the opencv documentation of it.
So, "global" variables are the only way to solve this problem. Alternatively, if you're looking for a nicer solution, you can create a wrapper class in which you have the namedWindow and the MouseCallback and a private member variable, which is manipulated when mouse callback function is called.
Related
I was trying to use the compute function in Flutter.
void _blockPressHandler(int row, int col) async {
// Called when user clicks any block on the sudoku board . row and col are the corresponding row and col values ;
setState(() {
widget.selCol = col;
}
});
bool boardSolvable;
boardSolvable = await compute(SudokuAlgorithm.isBoardInSudoku , widget.board , widget.size) ;
}
isBoardInSudoku is a static method of class SudokuAlgorithm. Its present in another file. Writing the above code , tells me that
error: The argument type '(List<List<int>>, int) → bool' can't be assigned to the parameter type '(List<List<int>>) → bool'. (argument_type_not_assignable at [just_sudoku] lib/sudoku/SudokuPage.dart:161)
How do i fix this? Can it be done without bringing the SudokuAlgorithm class's methods out of its file ? How to send multiple arguments to the compute function ?
static bool isBoardInSudoku(List<List<int>>board , int size ){ } is my isBoardInSudoku function.
Just put the arguments in a Map and pass that instead.
There is no way to pass more than one argument to compute because it is a convenience function to start isolates which also don't allow anything but a single argument.
Use a map. Here is an example:
Map map = Map();
map['val1'] = val1;
map['val2'] = val2;
Future future1 = compute(longOp, map);
Future<double> longOp(map) async {
var val1 = map['val1'];
var val2 = map['val2'];
...
}
In OOP and in general, it is more elegant to create a class for that with fields you need, that gives you more flexibility and less hassle with hardcoded strings or constants for key names.
For example:
boardSolvable = await compute(SudokuAlgorithm.isBoardInSudoku , widget.board , widget.size) ;
replace with
class BoardSize{
final int board;
final int size;
BoardSize(this.board, this.size);
}
...
boardSolvable = await compute(SudokuAlgorithm.isBoardInSudoku, BoardSize(widget.board, widget.size)) ;
Use a Tuple
Here is some example code from my app:
#override
Future logChange(
String recordId, AttributeValue newValue, DateTime dateTime) async {
await compute(
logChangeNoCompute, Tuple2<String, AttributeValue>(recordId, newValue));
}
Future<void> logChangeNoCompute(Tuple2<String, AttributeValue> tuple) async {
_recordsById[tuple.item1]!.setAttributeValue(tuple.item2);
await storage.setItem(AssetsFileName, toJson());
}
You can have a function whose only argument is a Map so that you can pass multiple parameters by passing a Map with properties and values. However, the problem that I'm encountering now is that I cannot pass functions. If the value of a Map's property is a function I get an error when I run the compute function.
This example works(keep in mind that I've imported libraries and that's the reason why some functions and classes definitions aren't in this example)
Future<List<int>> getPotentialKeys({
#required int p,
#required int q,
})async{
return await compute(allKeys,{
"p" : p,
"q" : q,
});
}
List<int> allKeys(Map<String,dynamic> parameters){
AdvancedCipherGen key = AdvancedCipherGen();
List<int> possibleE = key.step1(p: parameters["p"], q: parameters["q"]);
return possibleE;
}
This does not work(same thing with a function as the value of a property thows an error)
Future<List<int>> getPotentialKeys({
#required int p,
#required int q,
#required Function(AdvancedCipherGen key) updateKey,
})async{
return await compute(allKeys,{
"p" : p,
"q" : q,
"updateKey" : updateKey,
});
}
List<int> allKeys(Map<String,dynamic> parameters){
AdvancedCipherGen key = AdvancedCipherGen();
List<int> possibleE = key.step1(p: parameters["p"], q: parameters["q"]);
//TODO: Update the key value through callback
parameters["updateKey"](key);
return possibleE;
}
easily use a Class, you can Also Use Map or List But using class is Better and Cleaner
class MyFunctionInput{
final int first;
final int second;
MyFunctionInput({required this.first,required this.second});
}
change your function like this
doSomething(MyFunctionInput input){
}
and use it like below
compute(doSomething,MyFunctionInput(first: 1, second: 4));
See update 1 below for my guess as to why the error is happening
I'm trying to develop an application with some C#/WPF and C++. I am having a problem on the C++ side on a part of the code that involves optimizing an object using GNU Scientific Library (GSL) optimization functions. I will avoid including any of the C#/WPF/GSL code in order to keep this question more generic and because the problem is within my C++ code.
For the minimal, complete and verifiable example below, here is what I have. I have a class Foo. And a class Optimizer. An object of class Optimizer is a member of class Foo, so that objects of Foo can optimize themselves when it is required.
The way GSL optimization functions take in external parameters is through a void pointer. I first define a struct Params to hold all the required parameters. Then I define an object of Params and convert it into a void pointer. A copy of this data is made with memcpy_s and a member void pointer optimParamsPtr of Optimizer class points to it so it can access the parameters when the optimizer is called to run later in time. When optimParamsPtr is accessed by CostFn(), I get the following error.
Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime
has encountered a fatal error. The address of the error was at
0x6f25e01e, on thread 0x431c. The error code is 0xc0000005. This error
may be a bug in the CLR or in the unsafe or non-verifiable portions of
user code. Common sources of this bug include user marshaling errors
for COM-interop or PInvoke, which may corrupt the stack.'
Just to ensure the validity of the void pointer I made, I call CostFn() at line 81 with the void * pointer passed as an argument to InitOptimizer() and everything works. But in line 85 when the same CostFn() is called with the optimParamsPtr pointing to data copied by memcpy_s, I get the error. So I am guessing something is going wrong with the memcpy_s step. Anyone have any ideas as to what?
#include "pch.h"
#include <iostream>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace std;
// An optimizer for various kinds of objects
class Optimizer // GSL requires this to be an unmanaged class
{
public:
double InitOptimizer(int ptrID, void *optimParams, size_t optimParamsSize);
void FreeOptimizer();
void * optimParamsPtr;
private:
double cost = 0;
};
ref class Foo // A class whose objects can be optimized
{
private:
int a; // An internal variable that can be changed to optimize the object
Optimizer *fooOptimizer; // Optimizer for a Foo object
public:
Foo(int val) // Constructor
{
a = val;
fooOptimizer = new Optimizer;
}
~Foo()
{
if (fooOptimizer != NULL)
{
delete fooOptimizer;
}
}
void SetA(int val) // Mutator
{
a = val;
}
int GetA() // Accessor
{
return a;
}
double Optimize(int ptrID); // Optimize object
// ptrID is a variable just to change behavior of Optimize() and show what works and what doesn't
};
ref struct Params // Parameters required by the cost function
{
int cost_scaling;
Foo ^ FooObj;
};
double CostFn(void *params) // GSL requires cost function to be of this type and cannot be a member of a class
{
// Cast void * to Params type
GCHandle h = GCHandle::FromIntPtr(IntPtr(params));
Params ^ paramsArg = safe_cast<Params^>(h.Target);
h.Free(); // Deallocate
// Return the cost
int val = paramsArg->FooObj->GetA();
return (double)(paramsArg->cost_scaling * val);
}
double Optimizer::InitOptimizer(int ptrID, void *optimParamsArg, size_t optimParamsSizeArg)
{
optimParamsPtr = ::operator new(optimParamsSizeArg);
memcpy_s(optimParamsPtr, optimParamsSizeArg, optimParamsArg, optimParamsSizeArg);
double ret_val;
// Here is where the GSL stuff would be. But I replace that with a call to CostFn to show the error
if (ptrID == 1)
{
ret_val = CostFn(optimParamsArg); // Works
}
else
{
ret_val = CostFn(optimParamsPtr); // Doesn't work
}
return ret_val;
}
// Release memory used by unmanaged variables in Optimizer
void Optimizer::FreeOptimizer()
{
if (optimParamsPtr != NULL)
{
delete optimParamsPtr;
}
}
double Foo::Optimize(int ptrID)
{
// Create and initialize params object
Params^ paramsArg = gcnew Params;
paramsArg->cost_scaling = 11;
paramsArg->FooObj = this;
// Convert Params type object to void *
void * paramsArgVPtr = GCHandle::ToIntPtr(GCHandle::Alloc(paramsArg)).ToPointer();
size_t paramsArgSize = sizeof(paramsArg); // size of memory block in bytes pointed to by void pointer
double result = 0;
// Initialize optimizer
result = fooOptimizer->InitOptimizer(ptrID, paramsArgVPtr, paramsArgSize);
// Here is where the loop that does the optimization will be. Removed from this example for simplicity.
return result;
}
int main()
{
Foo Foo1(2);
std::cout << Foo1.Optimize(1) << endl; // Use orig void * arg in line 81 and it works
std::cout << Foo1.Optimize(2) << endl; // Use memcpy_s-ed new void * public member of Optimizer in line 85 and it doesn't work
}
Just to reiterate I need to copy the params to a member in the optimizer because the optimizer will run all through the lifetime of the Foo object. So it needs to exist as long as the Optimizer object exist and not just in the scope of Foo::Optimize()
/clr support need to be selected in project properties for the code to compile. Running on an x64 solution platform.
Update 1: While trying to debug this, I got suspicious of the way I get the size of paramsArg at line 109. Looks like I am getting the size of paramsArg as size of int cost_scaling plus size of the memory storing the address to FooObj instead of the size of memory storing FooObj itself. I realized this after stumbling across this answer to another post. I confirmed this by checking the value of paramsArg after adding some new dummy double members to Foo class. As expected the value of paramsArg doesn't change. I suppose this explains why I get the error. A solution would be to write code to correctly calculate the size of a Foo class object and set that to paramsArg instead of using sizeof. But that is turning out to be too complicated and probably another question in itself. For example, how to get size of a ref class object? Anyways hopefully someone will find this helpful.
A question by an MQL4 newbie.
What are the limits of what a void function can do in MQL4?.
I mean what can be done by a void function code and what can not be done?.
"void" only means that there is no return value from such function. So "returning a value" can not be done by a void function.
Hope that help....
you can put everything in a void function that you can put in a double, int, string, bool, ... function. What changes is what type of variable the function returns.
For instance, the following int function returns the sum of two values.
int sum( int a, int b )
{
return( a + b );
}
you could turn this function into a void function and instead of returning the value, you can print the value to the console.
void printsum( int a, int b )
{
Print( a + b );
}
In your follow up answer you ask about creating a void function that does something to a moving average. The following void function will accept different periods as input and print the MA. The function can't directly return the value of anything ( unless you use global variables / pass variables by reference ), but it can still accept values and do stuff based on those values.
void PrintMA( int period )
{
Print( iMA( NULL, 0, period, 8, MODE_SMMA, PRICE_MEDIAN, 1 ) );
}
The int function in your follow up answer only ever returns 0, so you could swap it to a void function and remove return(0) and it will work as before. Just change the function name first as start is a function name you should avoid using.
If you read the compile log, you'll be able to see why your above answer won't compile.
The only thing a void function(...) cannot do is to ever participate in an MQL4 assignment statement, i.e.:
someVariable = aVoidDeclaredFUNCTION();
Except this, one can do literally everything imaginable.
How that can be useful?
void aVoidDeclaredFUNCTION( const int thisParameterWillNeverChangeItsVALUE,
int &thisParameterWillBeAbleToChangeVALUE
){...}
Using a technique to pass by-Value, resp. to pass by-reference ( &passVariableByREF ) , even a void function(...) can process and "return"-results, if it is not enough to cause some actions in the void function(...){...} body, per-se.
"Void" just means the function doesn't return anything. These are useful for segmenting any stand alone sections of code (to make the code more organized for example, or to prevent repeating code... etc).
See this short video (not made by me) on the topic: Void Functions
You can write the prototypes without the variable names?
int example(examplestruct *var1, examplestruct *var2);
void done(examplestruct *var1,FILE *f);
struct {
int* field1;
int field2;
}examplestruct;
Is it possible to write the prototypes without name variables?
Can anyone tell me if this is acceptable in C language? You can write the prototypes without the variable names?
Yes.
As for the second question:
If you want a function to be inside main(), then take the body of the function, put it in main() and make sure that the arguments that the function had are well handled.
This example will clear things up:
#include <stdio.h>
void print(int);
void inc_p(int);
int main(void) {
int num = 5;
print(num);
inc_p(num);
// to get rid of inc_p(), copy paste it's body inside main
// and you will get this
// a++;
// print(a);
// However, a was an argument, here you need to use
// the variable declared in main(), i.e. 'num'
num++;
print(num);
return 0;
}
void print(int a) {
printf("%d\n", a);
}
void inc_p(int a) {
a++;
print(a);
}
Suppose I'm working with the following C snippet:
void inc(int *num) {*num++;}
void dec(int *num) {*num--;}
void f(int var) {
inc(&var);
dec(&var);
}
By using a static analyzer, I want to be able to tell if the value of var didn't change during the function's execution. I know I have to keep its state on my own (that's the point of writing a Clang checker), but I'm having troubles getting a unique reference of this variable.
For example: if I use the following API
void MySimpleChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol();
}
I'd expect it to return a pointer to this symbol's representation in my checker's context. However, I always get 0 into MyArg by using it this way. This happens for both inc and dec functions in the pre and post callbacks.
What am I missing here? What concepts did I get wrong?
Note: I'm currently reading the Clang CFE Internals Manual and I've read the excellent How to Write a Checker in 24 Hours material. I still couldn't find my answer so far.
Interpretation of question
Specifically, you want to count the calls to inc and dec applied to each variable and report when they do not balance for some path in a function.
Generally, you want to know how to associate an abstract value, here a number, with a program variable, and be able to update and query that value along each execution path.
High-level answer
Whereas the tutorial checker SimpleStreamChecker.cpp associates an abstract value with the value stored in a variable, here we want associate an abstract value with the variable itself. That is what IteratorChecker.cpp does when tracking containers, so I based my solution on it.
Within the static analyzer's abstract state, each variable is represented by a MemRegion object. So the first step is to make a map where MemRegion is the key:
REGISTER_MAP_WITH_PROGRAMSTATE(TrackVarMap, MemRegion const *, int)
Next, when we have an SVal that corresponds to a pointer to a variable, we can use SVal::getAsRegion to get the corresponding MemRegion. For instance, given a CallEvent, call, with a first argument that is a pointer, we can do:
if (MemRegion const *region = call.getArgSVal(0).getAsRegion()) {
to get the region that the pointer points at.
Then, we can access our map using that region as its key:
state = state->set<TrackVarMap>(region, newValue);
Finally, in checkDeadSymbols, we use SymbolReaper::isLiveRegion to detect when a region (variable) is going out of scope:
const TrackVarMapTy &Map = state->get<TrackVarMap>();
for (auto const &I : Map) {
MemRegion const *region = I.first;
int delta = I.second;
if (SymReaper.isLiveRegion(region) || (delta==0))
continue; // Not dead, or unchanged; skip.
Complete example
To demonstrate, here is a complete checker that reports unbalanced use of inc and dec:
// TrackVarChecker.cpp
// https://stackoverflow.com/questions/23448540/how-to-keep-track-of-a-variable-with-clangs-static-analyzer
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
using namespace clang;
using namespace ento;
namespace {
class TrackVarChecker
: public Checker< check::PostCall,
check::DeadSymbols >
{
mutable IdentifierInfo *II_inc, *II_dec;
mutable std::unique_ptr<BuiltinBug> BT_modified;
public:
TrackVarChecker() : II_inc(nullptr), II_dec(nullptr) {}
void checkPostCall(CallEvent const &Call, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
};
} // end anonymous namespace
// Map from memory region corresponding to a variable (that is, the
// variable itself, not its current value) to the difference between its
// current and original value.
REGISTER_MAP_WITH_PROGRAMSTATE(TrackVarMap, MemRegion const *, int)
void TrackVarChecker::checkPostCall(CallEvent const &call, CheckerContext &C) const
{
const FunctionDecl *FD = dyn_cast<FunctionDecl>(call.getDecl());
if (!FD || FD->getKind() != Decl::Function) {
return;
}
ASTContext &Ctx = C.getASTContext();
if (!II_inc) {
II_inc = &Ctx.Idents.get("inc");
}
if (!II_dec) {
II_dec = &Ctx.Idents.get("dec");
}
if (FD->getIdentifier() == II_inc || FD->getIdentifier() == II_dec) {
// We expect the argument to be a pointer. Get the memory region
// that the pointer points at.
if (MemRegion const *region = call.getArgSVal(0).getAsRegion()) {
// Increment the associated value, creating it first if needed.
ProgramStateRef state = C.getState();
int delta = (FD->getIdentifier() == II_inc)? +1 : -1;
int const *curp = state->get<TrackVarMap>(region);
int newValue = (curp? *curp : 0) + delta;
state = state->set<TrackVarMap>(region, newValue);
C.addTransition(state);
}
}
}
void TrackVarChecker::checkDeadSymbols(
SymbolReaper &SymReaper, CheckerContext &C) const
{
ProgramStateRef state = C.getState();
const TrackVarMapTy &Map = state->get<TrackVarMap>();
for (auto const &I : Map) {
// Check for a memory region (variable) going out of scope that has
// a non-zero delta.
MemRegion const *region = I.first;
int delta = I.second;
if (SymReaper.isLiveRegion(region) || (delta==0)) {
continue; // Not dead, or unchanged; skip.
}
//llvm::errs() << region << " dead with delta " << delta << "\n";
if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
if (!BT_modified) {
BT_modified.reset(
new BuiltinBug(this, "Delta not zero",
"Variable changed from its original value."));
}
C.emitReport(llvm::make_unique<BugReport>(
*BT_modified, BT_modified->getDescription(), N));
}
}
}
void ento::registerTrackVarChecker(CheckerManager &mgr) {
mgr.registerChecker<TrackVarChecker>();
}
bool ento::shouldRegisterTrackVarChecker(const LangOptions &LO) {
return true;
}
To hook this in to the rest of Clang, add entries to:
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td and
clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
Example input to test it:
// trackvar.c
// Test for TrackVarChecker.
// The behavior of these functions is hardcoded in the checker.
void inc(int *num);
void dec(int *num);
void call_inc(int var) {
inc(&var);
} // reported
void call_inc_dec(int var) {
inc(&var);
dec(&var);
} // NOT reported
void if_inc(int var) {
if (var > 2) {
inc(&var);
}
} // reported
void indirect_inc(int val) {
int *p = &val;
inc(p);
} // reported
Sample run:
$ gcc -E -o trackvar.i trackvar.c
$ ~/bld/llvm-project/build/bin/clang -cc1 -analyze -analyzer-checker=alpha.core.TrackVar trackvar.i
trackvar.c:10:1: warning: Variable changed from its original value
}
^
trackvar.c:21:1: warning: Variable changed from its original value
}
^
trackvar.c:26:1: warning: Variable changed from its original value
}
^
3 warnings generated.
I think you missed the check that this call event is a call to your function inc/dec. You should have something like
void MySimpleChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
const IdentifierInfo* callee = Call.getCalleeIdentifier();
if (callee->getName().str() == "inc" || callee->getName().str() == "dec")
SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol();
}