-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional (out) var parameters are not supported #102
Comments
You can use nil as default value to var type parameters.
|
That is an interesting idea. Unfortunately the real problem are the C lib functions with more than one optional out parameter, https://developer.gnome.org/gtk3/stable/GtkScale.html#gtk-scale-get-layout-offsets is one example but there are many more with up to 6 optional out parameters, 700 functions total. Can you give an example code for gtk-scale-get-layout-offsets() ? (The problem is for more than one, which one the user wants, and which one he wants to ignore. Passing NULL in C makes it clear.) |
Example code for gtk-scale-get-layout-offsets(): proc gtk_scale_get_layout_offsets (scale: ptr GtkScale, x: var gint = ignore(gint), y: var gint = ignore(gint))
var
scale = newGtkScale()
xval, yval: gint
gtk_scale_get_layout_offsets(scale, xval)
gtk_scale_get_layout_offsets(scale, y = yval) More complicated runnable example code: nilvar.c: #include <stdio.h>
typedef struct {
int a;
int b;
} CObj;
void cfunc(int* x, int* y, double* z, CObj* w) {
if(x == NULL) {
printf("ignore x\n");
} else {
printf("x = %d\n", *x);
*x = 123;
}
if(y == NULL) {
printf("ignore y\n");
} else {
printf("y = %d\n", *y);
*y = 987;
}
if(z == NULL) {
printf("ignore z\n");
} else {
printf("z = %f\n", *z);
*z = 100.0;
}
if(w == NULL) {
printf("ignore w\n");
} else {
printf("w = %d, %d\n", w->a, w->b);
w->a = 222;
w->b = 333;
}
} nilvar.nim: {.compile: "nilvar.c".}
template ignore(t: typed): untyped = cast[ptr t](nil)[]
type
CObj {.pure.} = object
a: cint
b: cint
proc cfunc(x: var cint = ignore(cint); y: var cint = ignore(cint); z: var cdouble = ignore(cdouble); w: var CObj = ignore(CObj)) {.importc.}
proc main =
cfunc()
var a: cint = 1
cfunc(a)
echo a
cfunc(y = a)
echo a
var b: cdouble = -1.0
cfunc(z = b)
echo b
var c = CObj(a: -1, b: -2)
cfunc(w = c)
echo c
main() Output:
|
Thanks, looks nice! |
We will have support for this in v0.8.4, try nimble install gintro@#head |
Simplest example is
https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-get-string
const gchar * g_variant_get_string (GVariant *value, gsize *length);
In C we can pass NULL for gsize if we are not interested in actual length. In Nim that parameter is a var parameter, and var parameters are never optional. Well for this case we can just create an overloaded proc without that parameter. It is not easy for the automatically created bindings, but at least we can do it manually.
But then there are functions like
https://developer.gnome.org/gtk3/stable/GtkScale.html#gtk-scale-get-layout-offsets
void gtk_scale_get_layout_offsets (GtkScale *scale, gint *x, gint *y);
x, y are both optional out parameters, in C we can pass NULL when we are not interested in one. In Nim both are var parameters.
Well, GTK has not that many functions with optional out parameters, only about 700, and most of them are not used that often. But still some support of optional var parameters would be nice.
For tuple results we have the underscore for optional results, so we could try to rewrite above proc as
proc getLayoutOffsets*(scale: Scale): (x, y: int) =
gtk_scale_get_layout_offsets(scale, result.x, result.y)
and may call it as
var y: int
(_, y) = getLayoutOffset(myscale)
Again, doing that conversion for tuple results is not really easy, but maybe possible.
Or may we support underscore for optional var parameters? Call proc like
var y: int
getLayoutOffsets(myscale, _, y)
We would need in the proc body a way to check if a parameter is _, which means we have to ignore it and pass NULL to C lib for it.
The text was updated successfully, but these errors were encountered: