2014-02-16 7 views
5

ich Emscripten lerne, und ich kann nicht einmal die grundlegendste String-Manipulation erhalten arbeiten, wenn Strings zwischen C++ und JS geben.Wie Zeichenketten zwischen C++ und Javascript passieren über Emscripten

Zum Beispiel würde Ich mag eine String-Länge-Funktion schreiben. In C++:

extern "C" int stringLen(std::string p) 
{ 
    return p.length(); 
} 

von Javascript Genannt als:

var len = _stringLen("hi."); 

Diese 0 für mich ergibt. Wie mache ich das wie erwartet? Welchen Stringtyp soll ich hier verwenden? char const*? std::wstring? std::string? Keins scheint zu arbeiten; Ich bekomme immer ziemlich zufällige Werte.

Dies ist nur der Anfang ... Wie kann ich dann eine Zeichenfolge aus C++ wie folgt zurückgeben?

extern "C" char *stringTest() 
{ 
    return "..."; 
} 

Und in JS:

var str = _stringTest(); 

Wieder kann ich diese Arbeit nicht einen Weg finden, zu machen; Ich bekomme immer Müll in JS.

So ist meine Frage klar: Wie kann ich String-Typen zwischen JS und C++ über Emscripten Marschall?

Antwort

0

Ein paar Gedanken:

  1. Die einzige Art, wie ich eine Methode aufgerufen haben, ist von crwap oder ccall mit?
    var length = Module.ccall('stringLen', ['string'], 'number');
  2. Haben Sie stringLen und stringTest in Ihrem EXPORTED_FUNCTIONS Parameter?
    emcc hello_world.cpp ... -s EXPORTED_FUNCTIONS=['_stringLen','_stringTest']

Werfen Sie einen Blick hier für weitere Informationen:
http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html

Oder mein hello_world Tutorial:
http://www.brightdigit.com/hello-emscripten/

Hoffentlich hilft.

6

extern "C" erkennt std :: string nicht.

Möglicherweise möchten Sie diese, um zu versuchen:
Test.cpp

#include <emscripten.h> 
#include <string.h> 

extern "C" int stringLen(char* p) 
     { 
      return strlen(p); 
     } 

Verwenden Sie den folgenden Befehl, um die CPP-Code zu kompilieren:

emcc Test.cpp -s EXPORTED_FUNCTIONS="['_stringLen'] 

Beispieltestcode:
Test.html

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>Hello World !</title> 
     <script src="a.out.js"></script> 
     <script> 
      var strLenFunction = Module.cwrap('stringLen', 'number', ['string']); 
      var len1 = strLenFunction("hi."); // alerts 3 
      alert(len1); 
      var len2 = strLenFunction("Hello World"); // alerts 11 
      alert(len2); 
     </script> 
    </head> 
</html> 
2

Wenn Sie extern "C" mit einer Funktion verwenden, können Sie C++ - Typen nicht in seiner Signatur verwenden.

Wenn Sie also std :: string verwenden möchten, können Sie "Embind" oder "WebIDL Binder" verwenden. Siehe here

Ich bevorzuge embind, also dies ist ein Beispielcode für Ihr Problem.

P.S Ich bin mir nicht sicher, wie man Variablen durch Verweis hier durchgibt, also nach Wert.

// This is your routine C++ code 
size_t MyStrLen(std::string inStr) { 
    return inStr.length(); 
} 

// This is the extra code you need to write to expose your function to JS 
EMSCRIPTEN_BINDINGS(my_module) { 
    function("MyStrLen", &MyStrLen); 
} 

Jetzt in JS alles, was Sie tun müssen, ist:

var myStr = "TestString"; 
Module.MyStrLen(myStr); 

Stellen Sie sicher, das Flag

--bind

beim Aufruf emcc passieren.

Es gibt another approach, wo Sie eine Malloc auf dem C++ - Heap von JS tun können und dann Manipulationen, aber der obige Ansatz sollte einfacher sein.