Purpose of GValue, GTypeValueTable, GTypeInfo and GParamSpec - gtk

GObject library is really awfully documented. It's damn hard to figure the purposes of entities created. Namely, I don't get the roles of GValue, GTypeValueTable, GTypeInfo, GParamSpec and TypeData.
In brief, the process of type registration is as follows. Each type is represented by a TypeNode structure. There are 2 storages of TypeNode structures: static_fundamental_type_nodes array for storing TypeNodes of static fundamental types and static_type_nodes_ht hash table for static non-fundamental types. Each GType is just the memory address of the corresponding TypeNode in case of non-fundamental types or index of TypeNode in static_fundamental_type_nodes in case of fundamental types. What happens to dynamic types - I don't know, please explain me if you can. The corresponding code resides in gtype_init function, responsible for initialization of the type system: http://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4323.
GValue, GParamSpec and GObject are GTypes themselves, so they are registered as types.
GValue is meant used to register new type values through it, but how?.
GParameters and GParamSpec seem to be required for registering GObject type (not sure). How exactly it is done? What are the roles of each?
MOST IMPORTANTLY: What are the roles of GTypeValueTable, GTypeInfo and TypeData? TypeData is referrenced by TypeNode and contains GTypeValueTable as well as substructures BoxedData, ClassData, IFaceData, InstanceData (why Instance, aren't we registering type?). Moreover, they seems to duplicate each other, cause ALL of them contain references to base_init/finalize, class_init/finalize has a reference to GTypeValueTable.
So, GObject papas, if you're reading this, please, explain yourselves! Describe the purpose of those structures you use.

The only two of these that you really need to care about unless you're attempting to work on some very low level code are GValue and GParamType
I'll start with GParamType
GParamType is for used for registering a property with a GObject. Say, for example, I have a GObject subclass called Person, and I wanted it to have two properties: Name and Age. In the class_init function I would register these like so
{
GParamSpec *pspec;
. . .
pspec = g_param_spec_string ("name", "Name", "The name of the person", "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_NAME, pspec);
pspec = g_param_spec_int ("age", "Age", "The age of the person", 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_AGE, spec);
. . .
}
Now you can call g_object_get or g_object_set on those properties and the system will know how to handle it
char *name;
int age;
g_object_set (G_OBJECT (person), "name", "Steve", "age", 37, NULL);
g_object_get (G_OBJECT (person), "name", &name, "age", &age, NULL);
g_print ("%s is %d years old\n", name, age);
// And because the type system knows when a property is a string, it knows how to give
// you a copy of the string, so you need to free it once you've finished with it
g_free (name);
The various parameters are explained here: GParamSpec There are GValue types for all the standard types: strings, bools, ints etc, and some other libraries such as GStreamer will register their own custom ones.
Outside of installing properties on GObjectClass you very rarely need to deal with GParamSpec. The two main occasions where they appear is in the GObjectClass set/get_property methods and the GObject notify signal. It is useful in the last case to detect which property has received the notify signal, by calling g_param_spec_get_name, but really it's better to use a more specific notify signal like so:
g_signal_connect (person, "notify::name", G_CALLBACK (name_changed_cb), NULL);
g_signal_connect (person, "notify::age", G_CALLBACK (age_changed_cb), NULL);
rather than
g_signal_connect (person, "notify", G_CALLBACK (something_changed_cb), NULL);
Sometimes you may want to create your own structures and use those for the properties. For example if I had
struct _PersonDetails {
char *name;
int age;
}
and instead of having two properties on the Person object, I wanted one called "details". The GLib type system does not know how to deal with my custom struct _PersonDetails so I would need to create a boxed type for it, so that it knew how to correctly copy/free the structure as it is passed around the Glib internals. And that is where GValue comes in.
GValue is for wrapping values of different types so they can be copied and freed correctly (if they need to be), and so that generic functions can be used.
For example, the GObjectClass method set_property has the prototype of
void set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
This means that any type which can be represented by a GValue can be passed in and specific functions such as set_int_property, set_string_property, set_bool_property are not required.
It also means that the functions g_object_set and g_object_get know how to deal with the parameters that are passed in because it knows that the property "name" is registered to be a string type, and it has the functions necessary to copy/free that string.
More about GValue can be found here - Generic values
To register our custom struct _PersonDetails with the GLib type system we would create a custom Boxed type which told the system how to copy and free it. The details are here: Boxed Types
G_DEFINE_BOXED_TYPE (PersonDetails, person_details,
person_details_copy,
person_details_free)
. . .
static gpointer
person_details_copy (gpointer data)
{
struct _PersonDetails *details = (struct _PersonDetails *)data;
struct _PersonDetails *copy = g_new (struct _PersonDetails, 1);
// We need to copy the string
copy->name = g_strdup (details->name);
copy->age = details->age;
return (gpointer) copy;
}
static void
person_details_free (gpointer data)
{
struct _PersonDetails *details = (struct _PersonDetails *)data;
// name was allocated so it needs freed as well
g_free (details->name);
g_free (details);
}
Now we can register our type using
pspec = g_param_spec_boxed ("details", "Details", "The person's details", person_details_get_type (), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DETAILS, pspec);

Related

Get the actual structure size before alignment

So it turns out that both dt struct and ?? sizeof struct return the total size the struct occupies in memory after alignment.
Is there a way to get the actual size of the struct before alignment?
I need this functionality for a function that returns the actual size of a field within a struct. For example:
__declspec(align(64)) struct ALIGNED_STRUCT {
char field;
}
running ?? sizeof(ALIGNED_STRUCT) one should get 0x40 which makes it hard to deduce the actual size of the internal field.
edit:
command outputs:
2:001> dt -v ALIGNED_STRUCT
test!ALIGNED_STRUCT
struct ALIGNED_STRUCT, 1 elements, 0x40 bytes
+0x000 field : Char
3:001> ?? sizeof(ALIGNED_STRUCT)
0x40
No -- there isn't a way to return the structure size "before alignment". That's not really meaningful in any case. The compiler is always using the aligned size. The symbols have the aligned size. That's the size of the type.
If you are looking for things like the "size of an internal field", there are numerous ways to accomplish this. As mentioned in comments, you can do the quick dirty EE sizeof thing:
dx sizeof(((ALIGNED_STRUCT *)0)->field)
You can also get full access to the underlying type system via the data model APIs (in either a C/C++ extension or in JavaScript) which will allow you to find out pretty much whatever you want about the types: their fields, sizes, offsets, function parameter types, template arguments, etc...
From C/C++, you can:
QI for IDebugHostSymbols (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgmodel/nn-dbgmodel-idebughostsymbols)
Get an IDebugHostModule (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgmodel/nn-dbgmodel-idebughostmodule) for the module containing your structure by calling the FindModuleByName method.
Get an IDebugHostType (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgmodel/nn-dbgmodel-idebughosttype) for the type you want to inquire about (e.g.: ALIGNED_STRUCT) by calling FindTypeByName
Enumerate its fields with EnumerateChildren, getting an IDebugHostField (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgmodel/nn-dbgmodel-idebughostfield) for each
Get the offset of such field by calling GetOffset
Get the type of each field by calling GetType, getting you back to another IDebugHostType
Get the size of the field by calling GetSize
That might look something like this:
ComPtr<IDebugHostSymbols> spHostSymbols; /* QI this off IDebugClient, etc... */
ComPtr<IDebugHostModule> spMyModule;
if (FAILED(spHostSymbols->FindModuleByName(USE_CURRENT_HOST_CONTEXT, L"myModule", &spMyModule)))
{
return ...;
}
ComPtr<IDebugHostType> spType;
if (FAILED(spMyModule->FindTypeByName(L"ALIGNED_STRUCT", &spType)))
{
return ...;
}
ComPtr<IDebugHostType> spType; /* get the type of an object */
//
// Enumerate every field of this type. Note thiat this *WILL NOT* enumerate
// fields of base classes!
//
ComPtr<IDebugHostSymbolEnumerator> spEnum;
if (SUCCEEDED(spType->EnumerateChildren(SymbolField, nullptr, &spEnum)))
{
ComPtr<IDebugHostSymbol> spFieldSymbol;
HRESULT hr = S_OK;
while (SUCCEEDED(hr))
{
hr = spEnum->GetNext(&spFieldSymbol);
if (SUCCEEDED(hr))
{
ComPtr<IDebugHostField> spField;
if (SUCCEEDED(spFieldSymbol.As(&spField))) /* should always succeed */
{
// spField is each field of the type in turn
}
ULONG64 fieldOffset;
if (SUCCEEDED(spField->GetOffset(&fieldOffset)) /* won't succeed on static fields */
{
// fieldOffset is the offset of the field within the type
}
ComPtr<IDebugHostType> spFieldType;
if (SUCCEEDED(spField->GetType(&spFieldType))
{
ULONG64 fieldSize;
if (SUCCEEDED(spFieldType->GetSize(&fieldSize)))
{
// fieldSize contains the size (aligned) of the field's type
}
}
}
}
// hr == E_BOUNDS : we hit the end of the enumerator
// hr == E_ABORT : user requested interruption, propagate upwards immediately
}
For C++, this can be made significantly easier by using the C++17 helper library on GitHub (https://github.com/microsoft/WinDbg-Libraries/blob/master/DbgModelCppLib/DbgModelClientEx.h)
That might look something like:
Module myModule(HostContext::DeferredCurrent(), L"myModule");
Type alignedStruct(myModule, L"ALIGNED_STRUCT");
//
// The below will *NOT* enumerate fields of base classes. You must explicitly
// recurse if you want such.
//
for(Field f : alignedStruct.Fields())
{
//
// Get the offset and size of each field.
//
ULONG64 fieldOffset = f.GetOffset();
ULONG64 fieldSize = f.Type().Size();
}
In JavaScript (see https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/native-objects-in-javascript-extensions-type-objects), this would look like:
Call host.getModuleType to get a type object for the structure (e.g.: ALIGNED_STRUCT)
Get access to the field in question by accessing the named property of fields on the type (e.g.: myType.fields.field_name)
Get the offset of of such field by accessing the offset property
Get the type of each field by accessing the type property
Get the size of the field by accessing the size property of its type
That might look something like:
var myType = host.getModuleType("myModule", "ALIGNED_STRUCT");
var fields = myType.fields;
//
// In JavaScript, fields has properties named according to each field. If
// you want to enumerate, get the property names and access those keys.
//
var fieldNames = Object.getOwnPropertyNames(fields);
for (var fieldName of fieldNames)
{
var field = fields[fieldName];
//
// Get the offset and size of each field...
//
var fieldOffset = field.offset;
var fieldSize = field.type.size;
}
In either of these cases, you would need to manually recurse base classes if you're looking at C++ objects where fields are contained in base classes.
Hope that helps...
William has provided a comprehensive answer this answer is just a practical example of that
0:000> dx #$stru
#$stru : Pcb _KPROCESS (+ 0x0)
name : Pcb
type : _KPROCESS
locationKind : member
offset : 0x0
0:000> dx #$stru.type.fields.Header.type.size
#$stru.type.fields.Header.type.size : 0x18
0:000>

OOP Terminology: class, attribute, property, field, data member

I am starting studying OOP and I want to learn what constitutes a class. I am a little confused at how loosely some core elements are being used and thus adding to my confusion.
I have looked at the C++ class, the java class and I want to know enough to write my own pseudo class to help me understand.
For instance in this article I read this (.. class attribute (or class property, field, or data member)
I have seen rather well cut out questions that show that there is a difference between class property and class field for instance What is the difference between a Field and a Property in C#?
Depending on what language I am studying, is the definition of
Property
Fields
Class variables
Attributes
different from language to language?
"Fields", "class variables", and "attributes" are more-or-less the same - a low-level storage slot attached to an object. Each language's documentation might use a different term consistently, but most actual programmers use them interchangeably. (However, this also means some of the terms can be ambiguous, like "class variable" - which can be interpreted as "a variable of an instance of a given class", or "a variable of the class object itself" in a language where class objects are something you can manipulate directly.)
"Properties" are, in most languages I use, something else entirely - they're a way to attach custom behaviour to reading / writing a field. (Or to replace it.)
So in Java, the canonical example would be:
class Circle {
// The radius field
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// The radius property
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
// We're doing something else besides setting the field value in the
// property setter
System.out.println("Setting radius to " + radius);
this.radius = radius;
}
// The circumference property, which is read-only
public double getCircumference() {
// We're not even reading a field here.
return 2 * Math.PI * radius;
}
}
(Note that in Java, a property foo is a pair of accessor methods called getFoo() and setFoo() - or just the getter if the property is read-only.)
Another way of looking at this is that "properties" are an abstraction - a promise by an object to allow callers to get or set a piece of data. While "fields" etc. are one possible implementation of this abstraction. The values for getRadius() or getCircumference() in the above example could be stored directly, or they could be calculated, it doesn't matter to the caller; the setters might or might not have side effects; it doesn't matter to the caller.
I agree with you, there's a lot of unnecessary confusion due to the loose definitions and inconsistent use of many OO terms. The terms you're asking about are used somewhat interchangeably, but one could say some are more general than others (descending order): Property -> Attributes -> Class Variables -> Fields.
The following passages, extracted from "Object-Oriented Analysis and Design" by Grady Booch help clarify the subject. Firstly, it's important to understand the concept of state:
The state of an object encompasses all of the (usually static) properties of the object plus the current (usually dynamic) values of each of these properties. By properties, we mean the totality of the object's attributes and relationships with other objects.
OOP is quite generic regarding certain nomenclature, as it varies wildly from language to language:
The terms field (Object Pascal), instance variable (Smalltalk), member object (C++), and slot (CLOS) are interchangeable, meaning a repository for part of the state of an object. Collectively, they constitute the object's structure.
But the notation introduced by the author is precise:
An attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class. Using the language-independent syntax, an attribute may have a name, a class, or both, and optionally a default expression: A:C=E.
Class variable: Part of the state of a class. Collectively, the class variables of a class constitute its structure. A class variable is shared by all instances of the same class. In C++, a class variable is declared as a static member.
In summary:
Property is a broad concept used to denote a particular characteristic of a class, encompassing both its attributes and its relationships to other classes.
Attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class.
Class variable is an attribute defined in a class of which a single copy exists, regardless of how many instances of the class exist. So all instances of that class share its value as well as its declaration.
Field is a language-specific term for instance variable, that is, an attribute whose value is specific to each object.
I've been doing oop for more than 20 years, and I find that people often use different words for the same things. My understanding is that fields, class variables and attributes all mean the same thing. However, property is best described by the stackoverflow link that you included in your question.
Generally fields, methods, static methods, properties, attributes and class (or static variables) do not change on a language basis... Although the syntax will probably change on a per language basis, they will be function in the way you would expect across languages (expect terms like fields/data members to be used interchangably across languages)
In C#....
A field is a variable that exists for a given instance of a class.
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field
protected int GetField
{
get
{
return _field;
}
}
}
Fields have a "visibility" this determines what other classes can see the field, so in the above example a private field can only be used by the class that contains it, but the property accessor provides readonly access to the field by subclasses.
A property lets you get (sometimes called an accessor) or set (sometimes called a mutator) the value of field... Properties let you do a couple of things, prevent writing a field for example from outside the class, change the visibility of the field (eg private/protected/public). A mutator allows you to provide some custom logic before setting the value of a field
So properties are more like methods to get/set the value of a field but provide more functionality
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field, but since it's visibility
// is protected only subclasses will know about this property
// (and through it the field) - The field and property in this case
// will be hidden from other classes.
protected int GetField
{
// This is an accessor
get
{
return _field;
}
// This is a mutator
set
{
// This can perform some more logic
if (_field != value)
{
Console.WriteLine("The value of _field changed");
_field = value;
OnChanged; // Call some imaginary OnChange method
} else {
Console.WriteLine("The value of _field was not changed");
}
}
}
}
A class or static variable is a variable which is the same for all instances of a class..
So, for example, if you wanted a description for a class that description would be the same for all instance of the class and could be accessed by using the class
eg.
public class BaseClass
{
// A static (or class variable) can be accessed from anywhere by writing
// BaseClass.DESCRIPTION
public static string DESCRIPTION = "BaseClass";
}
public class TestClass
{
public void Test()
{
string BaseClassDescription = BaseClass.DESCRIPTION;
}
}
I'd be careful when using terminology relating to an attribute. In C# it is a class that can be applied to other classes or methods by "decorating" the class or method, in other context's it may simply refer to a field that a class contains.
// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Some languages do not have "Attributes" like C# does (see above)
Hopefully that all makes sense... Don't want to overload you!
Firstly, you need to select a language. For example, I would recommend you to select Ruby language and community. Until you select a language, you cannot escape confusion, as different communities use different terms for the same things.
For example, what is known as Module in Ruby, Java knows as abstract class. What is known as attributes in some languages, is known as instance variables in Ruby. I recommend Ruby especially for its logical and well-designed OOP system.
Write the following in a *.rb file, or on the command line in irb (interactive Ruby interpreter):
class Dog # <-- Here you define a class representing all dogs.
def breathe # <-- Here you teach your class a method: #breathe
puts "I'm breathing."
end
def speak # <-- Here you teach your class another method: #speak
puts "Bow wow!"
end
end
Now that you have a class, you can create an instance of it:
Seamus = Dog.new
You have just created an instance, a particular dog of class Dog, and stored it in the constant Seamus. Now you can play with it:
Seamus.breathe # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak # <-- Invoking #speak instance method of Seamus
#=> Bow wow!
As for your remaining terminology questions, "property" or "attribute" is understood as "variable" in Ruby, almost always an instance variable. And as for the term "data member", just forget about it. The term "field" is not really used in Ruby, and "class variable" in Ruby means something very rarely used, which you definitely don't need to know at this moment.
So, to keep the world nice and show you that OOP is really simple and painless in Ruby, let us create an attribute, or, in Ruby terminology, an instance variable of Dog class. As we know, every dog has some weight, and different dogs may have different weights. So, upon creation of a new dog, we will require the user to tell us dog's weight:
class Dog
def initialize( weight ) # <-- Defining initialization method with one argument 'weight'
#weight = weight # <-- Setting the dog's attribute (instance variable)
end
attr_reader :weight # <-- Making the dog's weight attribute visible to the world.
end
Drooly = Dog.new( 16 ) # <-- Weight now must provide weight upon initialization.
Drooly.weight # <-- Now we can ask Drooly about his weight.
#=> 16
Remember, with Ruby (or Python), things are simple.
I discovered in my question that Properties as defined in .Net are just a convenience syntax for code, and they are not tied to underlying variables at all (except for Auto-Implemented Properties, of course). So, saying "what is the difference between class property and class field" is like saying: what is the difference between a method and an attribute. No difference, one is code and the other is data. And, they need not have anything to do with each other.
It is really too bad that the same words, like "attribute" and "property", are re-used in different languages and ideologies to have starkly different meanings. Maybe someone needs to define an object-oriented language to talk about concepts in OOP? UML?
In The Class
public class ClassSample
{
private int ClassAttribute;
public int Property
{
get { return ClassAttribute; }
set { ClassAttribute = value; }
}
}
In the Program
class Program
{
static void Main(string[] args)
{
var objectSample = new ClassSample();
//Get Object Property
var GetProperty = objectSample.Property;
}
}

Change G_PARAM_CONSTRUCT_ONLY property via inheritance

I try to inherit a gobject and, among other things, would like to change the value of a G_PARAM_CONSTRUCT_ONLY property so the next child class doesn't have to care.
Here's an example to depict this: GtkComboBox has a construct only property called "has-entry" with default value FALSE. In class A I want to change this value to TRUE, so that class B doesn't need to care.
GtkComboBoxClass <-- AClass <-- BClass
"has-entry" FALSE TRUE
The first naive approach was to use g_object_set() in A's instance_init function, but to no avail.
The next idea was to obtain the GParamSpec with g_object_class_find_property() and change the default value with g_param_value_set_default() in A's class_init function. But I suppose this to change the default for all GtkComboBoxClass derived objects.
The best idea I could come up with: If g_object_class_override_property() creates a new GParamSpec I could find this and set its default value in A's class_init function. But documentation doesn't loose a word about this.
So my question: Is this a working, and intended, way of accomplishing this, or is there a better solution?
Tried so far:
g_object_set() in instance init():
no warning on start
no effect
g_object_set() in GObjectClass->constructor():
no warning on start
no effect
warning on exit: invalid cast from GtkCellCiew to GtkEntry
g_object_set() in GObjectClass->constructed():
warning on start: can't be set after construction
Thanks
Stefan
if you want to set a property in a sub-class, and that property is construct-only, then you should use the constructed virtual function to call g_object_set() instead of the init virtual.
properties marked as construct-only will be applied during construction, using their default value, unless specified on the constructor itself — i.e. with g_object_new(). this means that setting a construct-only property inside init() will not suffice, as the value will be set after init() has been called. the constructed() virtual function, on the other hand, is called after the constructor properties have been applied, so it's possible to override the default value there.
Answering this for myself:
A look into gobject source reveals that the properties list given to constructor() contains all G_PARAM_CONSTRUCT and G_PARAM_CONSTRUCT_ONLY properties and their default or given values.
Modifying these values is undocumented (or at least I couldn't find it), but it works.
Construction time property values have to be modified in this list before chaining up to parents constructor, non construct properties have to be set afterwards. Example code looks like:
static GObject *constructor(GType gtype, guint n_properties, GObjectConstructParam *properties) {
GObject *object;
guint i;
gchar const *name;
GObjectConstructParam *property;
for (i = 0, property = properties; i < n_properties; ++i, ++property) {
name = g_param_spec_get_name(property->pspec);
if (!strcmp(name, "has-entry")) // is G_PARAM_CONSTRUCT_ONLY
g_value_set_boolean(property->value, TRUE);
}
object = G_OBJECT_CLASS(parent_class)->constructor(gtype, n_properties, properties);
g_object_set(object, "entry-text-column", TEXT_COLUMN, NULL);
return object;
}

UIA: Get ControlType from control type name (string)

Using Microsoft UI Automation. I have a string which represents UIA control type, like "Window" or "Button". I would like to get a ControlType object which fits this string. How to do it? Is some enumerations exists which represents all the UIA control types? I found only that ControlType has ControlType.LookupById(int) method. But I have to know correspondence between ID and name. Of course, I can create my own switch with all the possible UIA control types, or even use reflection to get all the members of ControlType factory. But I'm sure should be easier way..
I've found such way, using PresentationCore.dll, very strange for me, that such enum doesn't exist in standart UIA DLL. Also please pay attention, that there is a bug in ControlType class, I guess due to its private static constructor. If you call ControlType.LookupById(enumId) 1st time, it will return null, but in the 2nd time will be OK. The solution is quite simple -- just call ToString before usage, it will initialize the static constructor :)
using System.Windows.Automation.Peers;
// solving the bug with static constructor of ControlType..
ControlType.Button.ToString();
string controlTypeString = "Window";
AutomationControlType typeEnum;
bool result = Enum.TryParse(controlTypeString, true, out typeEnum);
if (result) typeEnum = (AutomationControlType)Enum.Parse(typeof(AutomationControlType), controlTypeString);
int enumId = (int)typeEnum + 50000;
ControlType controlType = ControlType.LookupById(enumId);

Timer Thread with passed Function* and Param

I'm working on finishing up my server for my first iPhone application, and I want to implement a simple little feature.
I would like to run a function (perhaps method as well), if another function returns a certain value after a certain waiting period. Fairly simple concept.... right?
Here's my basic foundation.
template <typename T,class TYP>
struct funcpar{
T (*function)(TYP);
TYP parameter;
funcpar(T (*func)(TYP),TYP param);
funcpar& operator=(const funcpar& fp);
};
The goal here is to be able to call funcpar::function(funcpar::parameter) to run the stored function and parameter, and not have to worry about anything else...
When I attempted to use a void* parameter instead of the template, I couldn't copy the memory as an object (because I didn't know what the end object was going to be, or the beginning for that matter) and when I tried multiple timers, every single object's parameter would change to the new parameter passed to the new timer... With the previous struct I have a
question:
Is it possible to make an all-inclusive pointer to this type of object inside a method of a class? Can I templatize a method, and not the whole class? Would it work exactly like a function template?
I have a managing class that holds a vector of these "jobs" and takes care of everything fairly well. I just don't know how to use a templatized function with the struct, or how to utilize templates on a single method in a class..
I'm also utilizing this in my custom simple threadpool, and that's working fairly well, and has the same problems...
I have another question:
Can I possibly store a function with a parameter before it's run? Something like toRun = dontrunmeyet(withThisParameter);? Is my struct even necessary?
Am I going about this whole thing incorrectly?
If this is overly ambiguous, I can set you up with my whole code for context
In order to create a class method that takes a template parameter, yes, it would work almost exactly like a function template. For example:
class A
{
public:
template<typename T>
void my_function(const T& value) { }
};
int main()
{
A test;
test.my_function(5);
return 0;
}
Secondly, for your structure, you can actually turn that into a functor-object that by overloading operator(), lets you call the structure as-if it were a function rather than having to actually call the specific function pointer members inside the structure. For instance, your structure could be re-written to look like this:
#include <iostream>
template <class ReturnType, class ParameterType>
class funcpar
{
private:
ReturnType (*function)(ParameterType);
ParameterType parameter;
public:
funcpar(ReturnType (*func)(ParameterType),ParameterType param):
function(func), parameter(param) {}
funcpar& operator=(const funcpar& fp);
//operator() overloaded to be a function that takes no arguments
//and returns type ReturnType
ReturnType operator() ()
{
return function(parameter);
}
};
int sample_func(int value)
{
return value + 1;
}
int main()
{
funcpar<int, int> test_functor(sample_func, 5);
//you can call any instance of funcpar just like a normal function
std::cout << test_functor() << std::endl;
return 0;
}
BTW, you do need the functor object (or your structure, etc.) in order to bind a dynamic parameter to a function before the function is called in C/C++ ... you can't "store" a parameter with an actual function. Binding a parameter to a function is actually called a closure, and in C/C++, creating a closure requires a structure/class or some type of associated data-structure you can use to bind a function with a specific parameter stored in memory that is used only for a specific instance of that function call.