I'm looking for a GObject cheat sheet, how common OOP concepts map to GObject's facilities. Consider for example:
AnyGObject *o;
o = anygobject_new();
Now, what are the conventions for...
calling a method
calling a method declared by a base class
calling a method declared by an interface the class is implementing
calling a class method
calling a class method declared by a base class
calling a virtual method
casting to a base class
casting to a derived class
casting to an interface the class is implementing
testing whether an object is of a particular type
...
Clarification:
The GObject Reference Manual and GObject HowTo explain at length how to create a new class (class struct, object struct, private struct, various macros, conventions). Taken together these facilities allow for OOP. Yet there seems to be no tutorial on how to use them consistently.
This answer assumes you are working with C. Other (usually object-oriented) languages have special bindings built to make working with GObject seem more natural.
If you've worked with GTK+, you already have done much of that list.
GObject methods are not members themselves (there is a vtable of sorts but it's only used for assigning virtual method implementations in a derived class when the class is first created). Instead, all methods in GObject are just plain functions, usually(?) prefixed by a method name prefix, and with the this pointer as the first argument.
For example, the C++ method
namespace Lib { // short for Library; to demonstrate GObject's idiomatic naming conventions
class Foo {
public:
void Bar(int z);
};
}
would be a plain function in the global namespace declared as
void lib_foo_bar(LibFoo *foo, int z);
and you would call it directly, just like any other C function.
Class derivation in GObject occurs by having the full data structure of the parent class as the first member of the derived class's data structure. For various reasons pertaining to rarely-discussed clauses in the C standard (and possibly the System V ABI and implementation of gcc, clang, and even the Microsoft C compilers), this means that a pointer to an object of the derived class is equivalent to a pointer to the parent class!
So if LibBaz derives from LibFoo, all you would need to say is
LibFoo *foobaz = (LibFoo *) baz;
and the same applies in reverse:
LibBaz *bazfoo = (LibBaz *) foo;
(This latter approach is what GTK+ uses for GtkWidget; I don't know if other GObject libraries do the same thing.)
Idiomatic GObject declarations include a bunch of macros that make the type conversions more terse while at the same time adding runtime type safety checks. Our LibFoo class would have the following macros:
#define LIB_TYPE_FOO (lib_foo_get_type())
#define LIB_FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LIB_TYPE_FOO, LibFoo))
With this, we would instead say
LibFoo *foobaz = LIB_FOO(baz);
LibBaz *bazfoo = LIB_BAZ(foo);
and if either baz or foo isn't the correct type for the conversion, a warning will be logged to standard error, which you can break at and investigate using a debugger.
(The lib_foo_get_type() function (and LIB_TYPE_FOO neatness macro) is important: it returns a numeric ID that maps to the type of LibFoo for future reference. If LibFoo doesn't have such a mapping, it will create the mapping, registering the type and creating the virtual method mappings.)
A similar macro allows type checking:
#define LIB_IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIB_TYPE_FOO))
which is a simple expression that can be used in an if statement.
So what about calling parent class methods? Well, if we put all of the above together, we have the answer:
lib_foo_parent_method(LIB_FOO(aLibBazInstance), params);
The same applies to virtual methods. Virtual methods are implemented using the GObject approximation to vtables and are transparent to the end programmer. All you will do is
lib_foo_virtual_method(LIB_FOO(whatever), params);
(If you actually build the derived class itself, the how of virtual methods becomes important.)
There are no static methods in GObject, because methods aren't tied to a class as closely as they are in real object-oriented languages. Just create a top-level method in your library:
void lib_something_common(params);
Finally, all of the above applies to interfaces. Interfaces work the exact same way to the end user; they use the same
void lib_iface_method(LibIface *iface, params);
approach to method calling, the same casting rules, and the same LIB_IFACE() and LIB_IS_IFACE() helper macros.
Hopefully that helps! Any further explanation would have to tread into explaining how to create a GObject, which I tried to keep outside the scope of this answer for simplicity's sake, but is a useful thing to know anyway.
Related
I am tasked to assist with the design of a dynamic library (exposed with a C interface) aimed to be used in embed software application on various embed platform (Android,Windows,Linux).
Main requirements are speed , and decoupling.
For the decoupling part : one of our requirement is to be able to facilitate integration and so permit backward compatibility and resilience.
My library have some entry points that should be called by the integrating software (like an initialize constructor to provide options as where to log, how to behave etc...) and could also call some callback in the application (an event to inform when task is finished).
So I have come with several propositions but as each of one not seems great I am searching advice on a better or standard ways to achieve decoupling an d backward compatibility than this 3 ways that I have come up :
First an option that I could think of is to have a generic interface call for my exposed entry points for example with a hashmap of key/values for the parameters of my functions so in pseudo code it gives something like :
myLib.Initialize(Key_Value_Option_Array_Here);
Another option is to provide a generic function to provide all the options to the library :
myLib.SetOption(Key_Of_Option, Value_OfOption);
myLib.SetCallBack(Key_Of_Callbak, FunctionPointer);
When presenting my option my collegue asked me why not use a google protobuf argument as interface between the library and the embed software : but it seems weird to me, as their will be a performance hit on each call for serialization and deserialization.
Are there any more efficient or standard way that you coud think of?
You could have a struct for optional arguments:
typedef struct {
uint8_t optArg1;
float optArg2;
} MyLib_InitOptArgs_T;
void MyLib_Init(int16_t arg1, uint32_t arg2, MyLib_InitOptArgs_T const * optionalArgs);
Then you could use compound literals on function call:
MyLib_Init(1, 2, &(MyLib_InitOptArgs_T){ .optArg2=1.2f });
All non-specified values would have zero-ish value (0, NULL, NaN), and would be considered unused. Similarly, when passing NULL for struct pointer, all optional arguments would be considered unused.
Downside with this method is that if you expect to have many new arguments in the future, structure could grow too big. But whether that is an issue, depends on what your limits are.
Another option is to simply have multiple smaller initialization functions for initializating different subsystems. This could be combined with the optional arguments system above.
In the chapter Boilerplate code of GObject Manual, when ViewerFile is declared as a final type using G_DECLARE_FINAL_TYPE, how can we add public data to it since it is hidden behind the viewer-file.c which is not included?
The main distinction between a "derivable" GObject type and a "final" GObject type is the visibility of the instance data structure.
If the GObject type is "derivable" then you can only use a private instance data structure, as the instance structure is public and it's generated to just include the parent's structure.
If the GObject type is "final" then you only get instance fields, since the instance data structure is private to your C source file.
You cannot mix the two approaches, unless you decide not to use the macros and write the boilerplate by hand.
Additionally, you should not ever access fields on an instance data structure; provide accessor functions, instead, so that you can validate pre-conditions and post-conditions safely.
I am trying to write bindings for a C library, specifically the libnfc. My current code is available on Github.
One of the central structures in the libnfc is the device. It is represented by the Go type Device.
type Device struct {
d *C.nfc_device
}
All functions inside the libnfc that operate on a Device are methods of it. Now, there are other C libraries (e.g. the libfreefare) whose APIs operates on nfc_devicees. For the sake of modularity, I want to place the code for each library I wrap into its own module. This leads to the problem, that I can't access private structure members from within other modules. I thought about the following solutions:
Make d a public member of Device
This would make it easy to access the underlying nfc_device from within other modules, but it makes it also easy to sidestep type safety. Additionally, I don't know whether cgo recognizes pointers to foreign types if they come from different modules. Finally, I lose flexibility if I change the structure of the Device type.
Add an accessor func (Device) GetCPtr() unsafe.Pointer
This solves the issues above but introduces the new issue that you suddently have access to an unsafe.Pointer in a module that might not even import unsafe.
Add an accessor func (Device) GetCPtr() uintptr
This solves the aforementioned issue, as you have to manually cast the result to get a proper pointer.
Are there any ways I missed? Is there a better, more idiomatic way to provide access to the underlying nfc_device?
I'm generally in favour with the third proposal of yours as this is the way the reflect package
handles this issue.
What you could also do is to expose only an interface in your libnfc wrapper, e.g.
type NFCDevice interface {
Read() ([]byte, error)
Write() ([]byte, error)
// ...
}
Now you have a public API that is safe.
Additionally, your device type implements a function
func (d *device) NfcDevice() *C.nfc_device {
return d.nfc_device
}
which you can use in your other wrappers by asserting your NFCDevice to implement the
interface
interface {
NfcDevice() *C.nfc_device
}
which you can create on the fly in the other wrappers. This way a programmer has to deliberately
do something to access the inner workings of your device.
What is the importance of Static keyword in Java and in C++ and how it's functionality differ in both programming languages ?
Maybe this link will give you a better idea: http://www.pp.rhul.ac.uk/~george/PH2150/html/node48.html
It has a visual diagram that may make it easier to understand.
There are 2 meanings for static. The first if you have a static variable, this means there is only 1 instance of this variable. It works pretty much the same in all programming languages with the keyword.
A static function is a function that can be called, even if the class it resides in is not instantiated. Static functions are necessary in C# and Java because you cant declare functions in these languages which have no encompassing class.
in C++, you can declare functions in the global namespace. In this language, static functions are used to denote that a function belongs to the class, but you dont have to instantiate the class to use the function. You could use a static function to access private variables of the class. Also note that in C++, static functions have a known memory address, so you can use function pointers to point to them without instantiating the class.
For Java, Understanding Instance and Class Members is a good place to start.
For C++, Microsoft has a reference on the static keyword.
There are many readily available programming language resources that will help you understand what the static keyword means. The above are two of them that I found with a quick Google search.
Use static for fields and methods that can only have one instance. That means they are not relevant to instances of a class, but to the class itself. For example the main thread (public static void main).
It works the same way in both languages. I assume you know what's object-oriented programming, and what's the difference between classes and objects/instances. So, if you mark a method or variable as "static", it operates on a class level, not instance level. All objects/instances share the same value of the "static" variable.
How can I create an array of namespaces? And because it seems like a long shot, if this is impossible, is there something similar to a namespace that can be made into an array?
The namespace, if it helps, contains these variables:
const int maxx=// depends on the particular namespace
// I need an array to go through each namespace and
// pick out the variable
const int maxy=// depends on particular namespace
//prgm is a class I made
prgm sector[maxx][maxy];
// another array of prgms. int is my shorthand of saying "depends on
// particular namespace", so is char.
prgm programs[int]={prgm1(int,int,char),prgm2(int,int,char)...
So any help would be welcome.
You could use reflection, but I think you should rethink your design.
I am not sure what language you are talking about, but in many (most?) languages, references to constants are replaced by the constant value at compile time. So they are no longer present at runtime and even reflection won't help.
You could create a class in each namespace that exposes the constants as (static) properties. Then you can use reflection to search the class in each namespace and obtain the constant values from the properties.
But, as mentioned by others, you should really rethink your design. Finally, namespaces are usually not accessable via reflection because they just extend the class names of the contained classes (and other stuff). Or is there a (non-esoteric) language that exposes namespaces as entities via reflection?
For .NET the reference for the System.Type.Namespace property states the following.
A namespace is a logical design-time naming convenience, used mainly to define scope in an application and organize classes and other types in a single hierarchical structure. From the viewpoint of the runtime, there are no namespaces.
Is this supposed to be C++? Sounds like you need to define a class, not a namespace, then create instances (objects) of that class and put them in an array.
So the sector variable gets tricky, since it is sized based on the value of maxx and maxy parameters that would be passed to the constructor of the class. You can take care of that problem by using a container class or a dynamically-allocated multi-dimensional array instead.
If you talk about C++, in there you can't pass namespaces as entities around. But you can do so with types, as type argument to templates. In this case, an MPL sequence could help together with MPL algorithms:
struct c1 { typedef int_<2> value_x; };
struct c2 { typedef int_<3> value_x; };
struct c3 { typedef int_<1> value_x; };
template<typename C> struct get_x : C::value_x { };
typedef vector<c1, c2, c3> scope_vec;
typedef max_element<
transform_view< scope_vec , get_x<_1> >
>::type iter;
You may then create your array like
prgm programs[deref< iter >::type::value];
Note that the search within that type-vector happens at compile time. So the value of the array is determined at compile time either.