After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 659278 - Virtual methods in compact classes
Virtual methods in compact classes
Status: RESOLVED DUPLICATE of bug 741465
Product: vala
Classification: Core
Component: Methods
0.13.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks: 792254
 
 
Reported: 2011-09-16 18:20 UTC by Andre Masella
Modified: 2018-03-27 10:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch to allow Berkeley DB-style virtual methods in compact classes in VAPI files (1.44 KB, patch)
2011-09-16 18:20 UTC, Andre Masella
none Details | Review

Description Andre Masella 2011-09-16 18:20:24 UTC
Created attachment 196767 [details] [review]
Patch to allow Berkeley DB-style virtual methods in compact classes in VAPI files

I was attempting to write a VAPI definition for Berkeley DB. The interface makes use of “virtual” methods implemented by function pointers in a structure, such as this:
int DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);

To create a VAPI, one would have to create something like:
delegate int PutMethod(DB db, Txn txn, DBT key, DBD data, uint32 flags);
[Compact]
class DB {
public PutMethod put;
}

and then always call it:
DB db;
db.put(db, ...);

Which seems ugly and impractical. I propose allow virtual methods in compact classes in VAPI files that obey this kind of behaviour. So, in the VAPI, have:
[Compact]
class DB {
public virtual int put(Txn txn, DBT key, DBD data, uint32 flags);
}

And this would allow:
db.put(txn, key, data, flags);
to generate the C code:
db->put(db, txn, key, data, flags);

Included is a proposed patch for this behaviour. It does not allow compact classes defined in Vala code to create this behaviour; only to consume it from existing APIs.
Comment 1 Andre Masella 2011-12-13 16:10:02 UTC
I have a workaround for developing a VAPI binding for BDB that allows calling the BDB-style virtual methods.

In a supplementary header file:
#define VPTR(instance, ...) instance->VPTR_METHOD(instance , ## __VA_ARGS__)

Then, in the VAPI binding
[Compact]
[CCode(free_function = "#undef VPTR_METHOD\n#define VPTR_METHOD free\nVPTR")]
class Foo {
	[CCode(cname = "#undef VPTR_METHOD\n#define VPTR_METHOD a_method\nVPTR")]
	public extern void a_method(int x);
	[CCode(cname = "#undef VPTR_METHOD\n#define VPTR_METHOD another_method\nVPTR")]
	public extern void another_method();
}

Vala codegen will convert:
foo.a_method(5);

into:
        #undef VPTR_METHOD
#define VPTR_METHOD a_method
VPTR (foo, 5);

and the preprocessor will then generate:

foo->a_method(foo, 5);

Unfortunately, this requires an extra header (unless there is a better way to inject arbitrary code) and creating a macro that can correctly handle deal with the comma in the function call is not portable. The VTPR macro above uses a GNU extension to drop the comma if the right token of the ## is empty.
Comment 2 Daniel Espinosa 2018-01-05 20:46:24 UTC
If original C is not portable, your solution on a portable header it is good even for the original project, may you want to contribute your workaround to help it to be portable.

For Vala compiler no virtual methods should be declared in compact classes and your bindings, using auxiliary declaration works for you, so no Vala related, then closing.
Comment 3 Rico Tzschichholz 2018-03-27 10:16:52 UTC

*** This bug has been marked as a duplicate of bug 741465 ***