Use nested functions as callbacks with Windows API functions? - function

I have the following code, this works.
import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;
void*[] hWndList;
extern (Windows) int callback(void* hWnd, long /* lParams */ ) nothrow {
hWndList ~= hWnd;
return true;
}
void main() {
EnumWindows(&callback, 0);
writeln(hWndList);
}
I was hoping I could use something more akin to JavaScript's syntax: (void* hWnd, long) => {}.
I tried this but I'm getting errors with the signature, it says the function is a delegate and apparently Windows API can't accept a delegate.
import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;
void main() {
void*[] hWndList;
EnumWindows((void* hWnd, long /* lParams */ ) nothrow {
hWndList ~= hWnd; return true;
}, 0);
writeln(hWndList);
}
I'm not going to even paste the compiler error because I am very clearly going about this the wrong way.
Of course there is nothing wrong with defining each callback as a separate function, but then comes the issue of naming them. I also don't like the way it makes my code look.
Thanks.

I figured out that I can cast the delegate (or lambda) to the correct signature specified by the MSDN documentation for EnumWindowsProc.
I also didn't realize that it was very bad practice to access the frame of the D program by implicitly using hWndList from the global scope.
This is what I used to create the correct signature.
alias EnumWindowsProc = extern (Windows) int function(HWND, LPARAM) nothrow;
Then I discovered that the alias already existed as ENUMWINDOWSPROC in the MinGW headers at core.sys.windows.windows at line 2483 (at the time of writing).
extern (Windows) nothrow {
...
alias BOOL function(HWND, LPARAM) ENUMWINDOWSPROC;
...
}
To solve the issue of implicitly passing D's frame, I used cast(LPARAM) &hWndList as the lParam in EnumWindows.
This became an issue of using the pointer now. I know this is probably botched, any suggestions welcome, but I casted it to a pointer.
*(cast(HWND[]*) lParam)
And the full code looks something like this. Obviously, this was just a minimal example to begin with, so you may want to assign the casted pointer to something so it's less confusing when using the variable from lParams.
import core.sys.windows.windows: EnumWindows, ENUMWINDOWSPROC;
import std.stdio: writeln;
void main() {
HWND[] hWndList;
EnumWindows(cast(ENUMWINDOWSPROC) (HWND hWnd, LPARAM lParam) {
*(cast(HWND[]*) lParam) ~= hWnd;
return true;
}, cast(LPARAM) &hWndList);
writeln(hWndList);
}
I hope this helps someone because this was confusing as hell for me (still not sure I understand the pointer logic).
Thanks to Boris-Barboris on the D Forums for giving me something to work from.
https://forum.dlang.org/post/xxklxaajptppockvazeo#forum.dlang.org

Related

How to create an async variadic function in Vala

Is it possible to create an async variadic function in Vala? If yes, how?
I couldn't find anything related in the Vala tutorial provided on the gnome website or in any example of code. My conclusion is that it's not possible, because vala requires async functions to have fixed arguments. But then, i don't know how to achieve something similar to a variadic function.
Example of code (non async, working without issues):
void long_function(string first_val, ...) {
var list = va_list();
string? second_val = list.arg();
print("%s,%s\n", first_val, second_val);
}
void main() {
long_function("a", "b");
}
Example of async code (not working):
async void long_function(string first_val, ...) {
var list = va_list();
string? second_val = list.arg();
print("%s,%s\n", first_val, second_val);
}
void main() {
long_function.begin("a", "b");
}
The error returned by the vala compiler (compiled with: vala --pkg gio-2.0 main.vala) is
main.vala:7.28-7.30: error: Argument 2: Cannot convert from `unowned string' to `void GLib.AsyncReadyCallback? (GLib.Object?, GLib.AsyncResult)'
My real use case scenario is (pseudo code):
async void fetch_from_api_with_params(...) {
// ExternalLibrary is a function which accepts a string with a url and any number of POST parameters
ExternalLibrary.fetch_from_url.begin("http://example.com", va_list());
// ...
}
Sadly, this is not possible with Vala. Vala uses C's variadic arguments system and GLib's co-routine system. Unfortunately, the two aren't compatible. Depending on your needs, you might be able to pass an array of Variant.

Overloading a function in go doesn't work

I have a function which currently doesn't receive a bool parameter, but then calls another function with a hardcoded bool. We need to remove the hardcoded call and allow a bool to be passed.
I first thought I could try some default parameter - my google searches resulted in that Go apparently doesn't support optional (resp. default) parameter.
So I thought I'd try function overloading.
I found this thread on reddit, which says that it works with a special directive since version 1.7.3:
https://www.reddit.com/r/golang/comments/5c57kg/when_did_function_overloading_get_slipped_in/
I am using 1.8, and still I couldn't get it to work.
I am not even sure I may be allowed to use that directive, but I was speculating that changing the function signature right away may be dangerous as I don't know who uses the function...
Anyway - even with //+overloaded it didn't work
Is there any "idiosyncratic" way or pattern to solve this problem in Go?
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
//result, err := anotherFunc(rpath, true)
return self.Apply(rpath, lpath, true)
}
When I run my test, I get (forgive me for omitting part of the real path to file):
too many arguments in call to self.Apply
have (string, string, bool)
want (string, string)
../remotesystem.go:178: (*RemoteSystem).Apply redeclared in this block
previous declaration at ../remotesystem.go:185
Overloading isn't available in Go. Instead of writing functions with the same name that do different things, it is preferable to be more expressive with what the function does in the function name. In this instance, what would commonly be done is something like this:
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
func (self *RemoteSystem) ApplyDynamic(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
return self.Apply(rpath, lpath, true)
}
Just by the name of the function, you can easily tell what is different and why.
Another example to provide some context (pun intended).
I write a lot of Google App Engine code in Go using go-endpoints. The way to log things is different depending on if you have a context or not. My logging functions ended up like this.
func LogViaContext(c context.Context, m string, v ...interface{}) {
if c != nil {
appenginelog.Debugf(c, m, v...)
}
}
func LogViaRequest(r *http.Request, m string, v ...interface{}) {
if r != nil {
c := appengine.NewContext(r)
LogViaContext(c, m, v...)
}
}
From the Reddit post:
Unicode. I can tell by the pixels.
Go doesn't support function overloading. But it does support using Unicode characters in function names, which allows you to write function names that look like other function names.
The first one is setValue, the second one is setV\u0430lue aka setV\xd0\xb0lue (with CYRILLIC SMALL LETTER A) and the third is setVal\U0001d69ee aka setVal\xf0\x9d\x9a\x9ee (with MATHEMATICAL MONOSPACE SMALL U).
See also:
Does the Go language have function/method overloading? (stackoverflow.com)
Why does Go not support overloading of methods and operators? (golang.org)
Alternative for function overloading in Go? (stackoverflow.com)

C++11: Why result_of can accept functor type as lvalue_reference, but not function type as lvalue_reference?

I've got program below:
#include<type_traits>
#include<iostream>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
struct S {
double operator()(){return 0.0;}
};
int f(){return 1;}
int main()
{
S obj;
call(obj);//ok
call(f);//error!
return 0;
}
It fails to compile in the line of "call(f)".
It's weird that "call(obj)" is OK.
(1) I've a similar post in another thread C++11 result_of deducing my function type failed. But it doesn't tell why functor objects are OK while functions are not.
(2) I'm not sure if this is related to "R call(F& f)": a function type cannot declare a l-value?
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Would you help to give some further explanations on "why" is my case, where did I get wrong?
Thanks.
The problem with call(f) is that you deduce F as a function type, so it doesn't decay to a function pointer. Instead you get a reference to a function. Then the result_of<F()> expression is invalid, because F() is int()() i.e. a function that returns a function, which is not a valid type in C++ (functions can return pointers to functions, or references to functions, but not functions).
It will work if you use result_of<F&()> which is more accurate anyway, because that's how you're calling the callable object. Inside call(F& f) you do f() and in that context f is an lvalue, so you should ask what the result of invoking an lvalue F with no arguments is, otherwise you could get the wrong answer. Consider:
struct S {
double operator()()& {return 0.0;}
void operator()()&& { }
};
Now result_of<F()>::type is void, which is not the answer you want.
If you use result_of<F&()> then you get the right answer, and it also works when F is a function type, so call(f) works too.
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
No, see above. Your call(F&) function takes its argument by reference, so there is no decay.
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Arrays don't decay when you pass them by reference either.
If you want the argument to decay then you should write call(F f) not call(F& f). But even if you do that you still need to use result_of correctly to get the result of f() where f is an lvalue.

Changing immutable members inside the constructor

void increment(ref int i)
{
++i;
}
class Class
{
immutable int member;
this(int parameter)
{
member = parameter;
++member; // okay
increment(member); // compile-time error
}
}
Why is ++member okay, but increment(member) isn't? Shouldn't both behave the same way?
Probably because the reference to increment isn't scope, so it has the potential to be escaped past the scope of the constructor, which would break the immutability of member, and the compiler can't verify that it's fine.
(It might be that scope won't work either, but it should. If implemented properly, I think scope would fix a lot of bugs like these, as well as providing for interesting optimizations. If it doesn't, I'd say it's a bug.)
I've pointed out semi-similar bugs before, but with delegates.
Const/immutable do have such problems in D.
What if increment was this?
int* p;
void increment(ref int i)
{
p = &i;
}
Uh oh, you've created a mutable reference to immutable data, breaking the type system.
I am guessing that
this(int parameter) {
member = parameter;
++member;
}
is an equivalent of
Class(int parameter): member(parameter+1) {}
in C++.
I think member field is not truly mutable in constructor, so compiler can optimize it to just init it. But it cannot do it with call to another function.
PS. It works on ideone: http://ideone.com/5ym5u

Non-void function used in void context?

I am using SystemVerilog. My code is:
function write_pixel_data(datastr ds);
/* some stuff here... but no return */
endfunction
then i am calling my function like:
write_pixel_data(someval);
And i get the vcs warning:
Warning-[SV-NFIVC] Non-void function used in void context.
But i am not returning anything, i know i can cast the function call to void to get rid of the warning. But why it gives this warning??!!
Thanks.
If you haven't declared the function as void and you call it without assigning the return value to anything, you'll see this error. Simple fix:
function void write_pixel_data(datastr ds);
/* some stuff here... but no return */
endfunction
Careful though, you can't do anything that 'takes time' in a function. You'll need a task for that.
A function declared with an implicit type returns logic. You must explicitly declare the return type to be void if that is your intention.