error: cannot convert 'GtkCheckButton*' {aka '_GtkCheckButton*'} to 'GtkWidget*' {aka '_GtkWidget*'} in initialization - gtk

So i have several check buttons I want to initialize and for some reason they are not working when i call them I get the error as shown in the title.
GtkComboBox* searchSetting = GTK_COMBO_BOX(application -> get_object("searchTypeSelecter"));
GtkWidget *checkAll = GTK_CHECK_BUTTON(application-> get_object("checkAll"));
GtkWidget *checkFood = GTK_CHECK_BUTTON(application-> get_object("checkFood"));
GtkWidget *checkFuel = GTK_CHECK_BUTTON(application-> get_object("checkFuel"));
GtkWidget *checkParking = GTK_CHECK_BUTTON(application-> get_object("checkParking"));
My partner made several objects from other things(not check buttons) like he did with searchSetting, and that worked perfectly fine. What am I doing wrong here?

The reason why you're seeing this is because you're doing what the error message mentions: you're casting the result of application->get_object(), whatever return type that may have, as GtkCheckButton*. In other words, you're doing something like this:
GtkWidget *a = (GtkCheckButton*) b; // Doesn't even matter how b was declared earlier
GTK's widgets are written in C, so they don't have a concept of polymorphism. To the compiler, they're just pointers, and the "OOP" that GTK (and its underlying framework GObject) uses, requires you to also "upcast" variables where needed. In other words, you have 2 options:
Cast to GtkCheckButton* and upcast to GtkWidget when using GtkWidget API.
GtkCheckButton *checkAll = GTK_CHECK_BUTTON(application-> get_object("checkAll"));
// later...
gtk_widget_show(GTK_WIDGET(checkAll));
Cast to GtkWidget*:
GtkWidget *checkAll = GTK_WIDGET(application-> get_object("checkAll"));
// later...
gtk_widget_show(checkAll);

Related

How to use parametrized member function of a struct in callback?

I have a struct that looks like the one below
struct dc_callback
{
int
my_configure_event(
GtkWidget *widget,
GdkEventConfigure *event,
struct LoadData *myData)
{
...others
return TRUE;
}
//Parametrized Constructor
int
my_draw(
GtkWidget *widget,
cairo_t *cr,
struct LoadData *myData)
{
...others
return TRUE;
}
};
It has two parametrized member function that I intend to call from g_signal_connect for some nth time.
main(){
int i;
dc_callback dc_callback_instance[nth];
for(i=0;i<nth;i++){
g_signal_connect(widget_list[i],"draw",G_CALLBACK(dc_callback_instance[i].my_draw),myData);
g_signal_connect(widget_list[i],"configure-event",G_CALLBACK(dc_callback_instance[i].my_configure_event),myData);
}
}
However, during compile time, I get an error regarding invalid use of member function int dc_callback::my_draw(args). It ask me to add () but that could not be done since the G_CALLBACK accepts function name without its attached argument.
How to I accomplish this?
The answer of #0x5453 is correct except for my_draw_cbk and its call : it shall be
gboolean my_draw_cbk ( GtkWidget *widget,
cairo_t *cr,
struct CallbackData *cbData)
{
cbData->dc_callback_inst.my_draw(widget, cr, cbData->otherData);
return TRUE;
}
and to connect the signal :
// cbData shall be free with g_free when no longer needed
CallbackData* cbData = g_new(CallbackData, 1);
// set the cbData values..
g_signal_connect(widget_list[i],"draw",G_CALLBACK(my_draw_cb),cbData);
G_CALLBACK expects a (non-member) function pointer, and you are not using the proper syntax for passing a function pointer. However, there is a bigger issue: Function pointers and member function pointers are different concepts in C++. You cannot pass a member function pointer to an interface that expects a standard function pointer.
So, how to associate the invocation of the callback with your dc_callback instance?
Traditionally when working with C-style API's, you have to provide a free function for the callback that takes your instance (and any extra data) as a void* parameter. Then inside the callback, you can cast the void* back to the original type. In your case, this could look something like:
struct CallbackData {
dc_callback& dc_callback_inst;
Foo otherData; // whatever else you need to capture here
};
void my_draw_cb(void* data) { // g_signal_connect might pass more params to cb in addition to data
CallbackData& cbData = *(CallbackData*)data;
cbData->dc_callback_inst.my_draw(cbData->otherData);
}
// ...
for(i=0;i<nth;i++){
CallbackData cbData{dc_callback_instance[i], myData};
g_signal_connect(widget_list[i],"draw",G_CALLBACK(&my_draw_cb),cbData);
// ...
}

How to use macros to replace/inject function calls in OpenCL

I am developing an algorithm using PyOpenCL. To avoid code duplication I am trying to use templating along with C macros to replace function calls, since OpenCL 1.2 does not support function pointers.
I currently have the following macro section in my OpenCL kernel code:
#define LINEAR_FIT_SEARCH_METHOD ${linear_fit_search_method}
#if LINEAR_FIT_SEARCH_METHOD == MIN_MAX_INTENSITY_SEARCH
#define LINEAR_FIT_SEARCH_METHOD_CALL() determineFitUsingMinMaxIntensitySearch(lineIntensities,imgSizeY,linFitParameter,linFitSearchRangeXvalues)
#elif LINEAR_FIT_SEARCH_METHOD == MAX_INCLINE_SEARCH
#define LINEAR_FIT_SEARCH_METHOD_CALL() determineFitUsingInclineSearch(lineIntensities,imgSizeY,linFitParameter,linFitSearchRangeXvalues,inclineRefinementRange)
#endif
In the kernel code I also define the corresponding functions determineFitUsingMinMaxIntensitySearch and determineFitUsingInclineSearch. I am now attempting to use the macro to exchange the function call like this:
__private struct linearFitResultStruct fitResult = LINEAR_FIT_SEARCH_METHOD_CALL();
so that I select the desired call (note: I always only need either one or the other and configuration is done before the program runs (no need for dynamically switching the two)).
Using PyOpenCL templating I now do something like this:
def applyTemplating(self):
tpl = Template(self.kernelString)
if self.positioningMethod == "maximumIntensityIncline":
linear_fit_search_method="MAX_INCLINE_SEARCH"
if self.positioningMethod == "meanIntensityIntercept":
linear_fit_search_method="MIN_MAX_INTENSITY_SEARCH"
rendered_tpl = tpl.render(linear_fit_search_method=linear_fit_search_method)
self.kernelString=str(rendered_tpl)
Where self.kernelString contains the macro above along with the code.
Unfortunately I am getting this error, which I do not understand:
1:455:53: error: implicit declaration of function 'determineFitUsingInclineSearch' is invalid in OpenCL
1:9:41: note: expanded from macro 'LINEAR_FIT_SEARCH_METHOD_CALL'
1:455:41: error: initializing 'struct linearFitResultStruct' with an expression of incompatible type 'int'
1:536:30: error: conflicting types for 'determineFitUsingInclineSearch'
1:455:53: note: previous implicit declaration is here
1:9:41: note: expanded from macro 'LINEAR_FIT_SEARCH_METHOD_CALL'
1:616:41: error: initializing 'struct linearFitResultStruct' with an expression of incompatible type 'int'
I have very little experience with macros so:
Is what I am attempting even possible in this way or do I need to go a different route?
UPDATE 1:
This code runs fine when I set self.positioningMethod = "meanIntensityIntercept" in my unit test, but fails when setting self.positioningMethod = "maximumIntensityIncline" with the error message above. I cannot spot the error at the yet.
UPDATE 2:
I was also inspired by this post, if that helps:
how to compare string in C conditional preprocessor-directives
As you say you have very little experience with macros then I would go for something simple. determineFitUsingMinMaxIntensitySearch and determineFitUsingInclineSearch accept different number of arguments, so this could done this way:
kernel_code = """
#ifdef USE_FUNCTION_A
void function_a(
int x,
int y,
int extra_param,
__global const int* restrict in,
__global int* restrict out
)
{
//...
}
#else
void function_b(
int x,
int y,
__global const int* restrict in,
__global int* restrict out
)
{
//...
}
#endif
__kernel void my_kernel(
int x,
int y,
__global const int* restrict in,
__global int* restrict out
)
{
// ...
#ifdef USE_FUNCTION_A
function_a(x,y,5,in,out);
#else
function_b(x,y,in,out);
#endif
// ...
}
"""
if use_function_a:
prg = cl.Program(ctx, kernel_code).build("-DUSE_FUNCTION_A")
else:
prg = cl.Program(ctx, kernel_code).build("")

std::vector in MyClass ptr causing crash on destructor

I have a problem in regards to a custom class I have made. The original intention was to create a particle emitter and in this emitter are two vectors to hold colors and the particles themselves.
The problem exactly is trying to destruct this custom class which functions perfectly if you do not call the destructor, which is obviously bad.
I have reduced this to a very short, compileable example.
Test.h
#include <vector>
class Test{
public:
Test();
~Test();
protected:
std::vector<int> Ints;
};
And the main.cpp:
#include "Test.h"
int main(int argc, char **argv){
Test* t;
delete[] t;
return 0;
}
In the Implementation file is just empty constructor and destructors.
Something to note is, this only happens when the "Test" is a pointer, which would preferred to be avoided.
Will provide more information if needed. Thanks in advance.
You are deleting something that hasn't allocated a memory and that too in wrong way.
Allocate memory first
Test *t = new Test;
then,
delete t; // Note no []
Also, since C++11 is tagged, prefer using smart pointers, which do the memory management for you on its own
If t is a pointer then you need to give it something to point to first, as #P0W points out. But why not just declare t to be a local (stack) variable?
#include "Test.h"
int main(int argc, char **argv){
Test t;
return 0;
}
You are not creating object Test. You have created an pointer of type Test. For a pointer you need to use the keyword "new".
Test * t = new Test();

Call function in main program from a library in Arduino

I've just started making libraries in Arduino. I've made a library named inSerialCmd. I want to call a function named delegate() that is defined in the main program file, stackedcontrol.ino, after the inSerialCmd library is included.
When I try to compile, one error is thrown:
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: In member function
'void inSerialCmd::serialListen()':
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: error:
'delegate' has not been declared
After doing a bit of searching, it seemed that adding the scope resolution operator might do the trick. So I added the "::" before delegate(), now "::delegate()", but the same error is thrown.
Now I'm stumped.
You cannot and should not directly call a function in a program from a library. Keep in mind a key aspect that makes a library into a library:
A library does not depend on the specific application. A library can be fully compiled and packaged into the .a file without the existence of a program.
So there is a one way dependency, a program depends on a library. This at first glance may seem to prevent you from achieving what you want. You can achieve the functionality you are asking about through what is sometimes referred to as a callback. The main program would provide to the library at runtime a pointer to the function to execute.
// in program somwehere
int myDelegate(int a, int b);
// you set this to the library
setDelegate( myDelegate );
You see this in the arduino if you look at how interrupt handlers are installed. This same concept exists in many environments - event listeners, action adapters - all with the same goal of allowing a program to define the specific action that a library cannot know.
The library would store and call the function via the function pointer. Here is a rough sketch of what this looks like:
// in the main program
int someAction(int t1, int t2) {
return 1;
}
/* in library
this is the delegate function pointer
a function that takes two int's and returns an int */
int (*fpAction)(int, int) = 0;
/* in library
this is how an application registers its action */
void setDelegate( int (*fp)(int,int) ) {
fpAction = fp;
}
/* in libary
this is how the library can safely execute the action */
int doAction(int t1, int t2) {
int r;
if( 0 != fpAction ) {
r = (*fpAction)(t1,t2);
}
else {
// some error or default action here
r = 0;
}
return r;
}
/* in program
The main program installs its delegate, likely in setup() */
void setup () {
...
setDelegate(someAction);
...

Using boost::program_options with own template class possible?

I'm currently start using boost::program_options for parsing command line options as well as configuration files.
Is it possible to use own template classes as option arguments? That means, something like
#include <iostream>
#include "boost/program_options.hpp"
namespace po = boost::program_options;
template <typename T>
class MyClass
{
private:
T* m_data;
size_t m_size;
public:
MyClass( size_t size) : m_size(size) { m_data = new T[size]; }
~MyClass() { delete[] m_data; }
T get( size_t i ) { return m_data[i]; }
void set( size_t i, T value ) { m_data[i] = value; }
};
int main (int argc, const char * argv[])
{
po::options_description generic("General options");
generic.add_options() ("myclass", po::value< MyClass<int>(2) >(),
"Read MyClass");
return 0;
}
Trying to compile this I get an Semantic Issue (No matching function for call to 'value'). I guess I need to provide some casting to an generalized type but I have no real idea.
Can anybody help?
Thanks
Aeon512
I wouldn't know if boost::program_options allows the use-case you are trying, but the error you are getting is because your are trying to pass an object as a template type to po::value<>. If the size is known at compile-time, you could have the size be passed in as a template parameter.
template< typename T, size_t size >
class MyClass {
T m_data[size];
public:
// ...
};
And then use it like so:
po::value< MyClass<int, 2> >()
You should also look into using Boost.Array instead that I guess fulfills what you are trying to implement.
I would write it like this:
MyClass<int> mine(2);
generic.add_options() ("myclass", po::value(&mine), "Read MyClass");
Then all that needs to be done is to define an input stream operator like this:
std::istream& operator >>(std::istream& source, MyClass& target);
Then Boost Program Options will invoke this stream operator when the myclass option is used, and your object will be automatically populated according to that operator's implementation, rather than having to later call one of the Program Options functions to extract the value.
If you don't prefer the above syntax, something like should work too:
generic.add_options() ("myclass", po::value<MyClass<int> >()->default_value(MyClass<int>(2)), "Read MyClass");
This way you would be creating the instance of your class directly with your desired constructor argument outside of the template part where runtime behavior isn't allowed. I do not prefer this way because it's verbose and you end up needing to call more functions later to convert the value.