2015-07-14 27 views
5


Mam duże tablice liczbowe w JS, które chcę przekazać do C++ do przetworzenia. IMHO najbardziej skutecznym sposobem jest umożliwienie JS napisać bezpośrednio do C++ sterty i przekazać wskaźnik jako argumentu w bezpośredniej rozmowy, jak:Przekazywanie tablicy liczb JS do emscripten C++ bez reinterpret_cast

var size = 4096, 
    BPE = Float64Array.BYTES_PER_ELEMENT, 
    buf = Module._malloc(size * BPE), 
    numbers = Module.HEAPF64.subarray(buf/BPE, buf/BPE + size), 
    i; 
// Populate the array and process the numbers: 
parseResult(result, numbers); 
Module.myFunc(buf, size); 

C++ funkcje przetworzyć numery wyglądać następująco:

void origFunc(double *buf, unsigned int size) { 
    // process the data ... 
} 
void myFunc(uintptr_t bufAddr, unsigned int size) { 
    origFunc(reinterpret_cast<double*>(bufAddr), size); 
} 

to działa zgodnie z oczekiwaniami, ale zastanawiam się, czy istnieje jakakolwiek szansa, aby wywołać origFunc bezpośrednio z JavaScript, żeby pozbyć myFunc i brzydkiegoreinterpret_cast.
Kiedy próbowałem powiązać origFunc poprzez:

EMSCRIPTEN_BINDINGS(test) { 
    function("origFunc", &origFunc, emscripten::allow_raw_pointers()); 
} 

... i nazwać go bezpośrednio:

Module.origFunc(buf, size); 

pojawia się błąd:
Uncaught UnboundTypeError: nie można nazwać origFunc powodu niezwiązanych typów : Pd

Czy jest to ogólne ograniczenie emscriptena, czy istnieją "mniej brudne" rozwiązania niż reinterpret_cast obejść?

+0

Nie emscripten dobrze wiem, ale wygląda na to, modyfikować lokalizację przydzielona tablica 'buf/BPE' przed przekazaniem jej do funkcji. Podejrzewam, że musi to być 'buf'. I prawdopodobnie argument size dla funkcji powinien być po prostu "size * BPE". – Niall

+0

Błąd mówi o typie 'Pd', ale fragmenty kodu nie pokazują' Pd', co to jest 'Pd'? – Niall

+0

IMHO "Pd" pochodzi z emscripten i pozostaje dla "Pointer double" –

Odpowiedz

0

Można użyć static_cast jeśli

  • określić, że funkcja trwa void * zamiast uintptr_t;

  • nie używać EMSCRIPTEN_BINDINGS, ale użyć EMSCRIPTEN_KEEPALIVE + cwrap/ccall sposób komunikowania JS-> C++. Z jakiegoś powodu metoda EMSCRIPTEN_BINDINGS spowodowała wyjątek od getTypeName is not defined, gdy go wypróbowałem.

Więc funkcja wygląda następująco:

extern "C" int EMSCRIPTEN_KEEPALIVE myFunc(void *bufAddr, unsigned int size) { 
    origFunc(static_cast<double *>(bufAddr), size); 
    return 0; 
} 

które mogą być wywoływane z JavaScript przez

Module.ccall('myFunc', 'number' ['number', 'number'], [buf, size]);