Pergunta

I'm writing a C++ library for node.js, using v8. I'm on Windows, and I want to call an Win32 API function, EnumWindows, from my C++ code. EnumWindows takes a callback function and optional callback function parameter as parameters. My only goal with this C++ library is to expose EnumWindows to javascript-land, and be used like follows ...

mymodule.EnumWindows(function (id) { ... });

So, my C++ code looks like this ...

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    // re-cast the Local<Function> and call it with hWnd
    return true;
}

Handle<Value> EnumWindows(const Arguments& args)
{
    HandleScope scope;

    // store callback function
    auto callback = Local<Function>::Cast(args[0]);

    // enum windows
    auto result = EnumWindows(EnumWindowsProc, callback);

    return scope.Close(Boolean::New(result == 1));
}

My question is how can I pass the Local<Function, in my EnumWindows wrapper, to the EnumWindowsProc callback function? The EnumWindowsProc is executed in the same thread.

Foi útil?

Solução

You could pass the address of the callback:

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    Local<Function>& f = *reinterpret_cast<Local<Function>*>(lParam);

    // use f

    return true;
}

Handle<Value> EnumWindows(const Arguments& args)
{
    HandleScope scope;

    // store callback function
    auto callback = Local<Function>::Cast(args[0]);

    // enum windows
    auto result = EnumWindows(EnumWindowsProc,
                              reinterpret_cast<LPARAM>(&callback));

    return scope.Close(Boolean::New(result == 1));
}

Another option would be just collecting the handles to process them later:

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    std::vector<HWND>* p = reinterpret_cast<std::vector<HWND>*>(lParam);
    p->push_back(hWnd);
    return true;
}

Handle<Value> EnumWindows(const Arguments& args)
{
    HandleScope scope;

    // store callback function
    auto callback = Local<Function>::Cast(args[0]);

    // enum windows
    std::vector<HWND> handles;
    auto result = EnumWindows(EnumWindowsProc,
                              reinterpret_cast<LPARAM>(&handles));

    // Do the calls...

    return scope.Close(Boolean::New(result == 1));
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top