Wednesday, February 21, 2018

Stey by Step running C++ in your web page by using WebAssembly

    WebAssembly has been supported by the most of the modern web browsers. That means you can run C or C++ directly on your web page!


    Today, JavaScript is executed in a virtual machine in your browsers. JavaScript is one of the fastest dynamic languages around. It's fast but It still can not compete with raw C or C++ code. What if we could use that virtual machine to run C/C++? That's exactly what WebAssembly does! Also WebAssembly can communicate to JavaScript since both are running on the same virtual machine.

    To be able to run C or C++ on a webpage, first we need to create a C++ program and compile it as .wasm file. If your browser supports WebAssembly, It will recognize the .wasm file. From that point, by using a JavaScript file called "JavaScript glue code", we can add .wasm file to our web page. I am sure we will have a lot of webassembly frameworks in future so you may not need to do all of these steps in future.

    I am going to use Emscripten to compile my C++ into WebAssembly file. You can download for free from here. I have created the following simple C++ code  in Visual Studio 2017.

#include "emscripten/emscripten.h"

int main(int argc, char ** argv) {
    printf("WebAssembly module is loaded!\n");
}
extern "C" {
int EMSCRIPTEN_KEEPALIVE GetTemparature(int zipcode) {
    return 72;
}
}

   When the webassembly file is loaded to your browser, It will call the main function and you will see "WebAssembly module is loaded" in your browser's console. Also we want the GetTemparature function available so Javascript can call it whenever. That's why we add EMSCRIPTEN_KEEPALIVE to the function. That is defined in emscripten.h and that's why we are adding the header file on top. Without that, compiler will not add this function into webassembly file and you can not call it from JavaScript.  Now, Let's compile this simple C++ code.

emcc wasm1.cpp -s WASM=1 -O3 -o index.js

 wasm1.cpp is the name of the C++ file
-s WASM-1 tells to compiler to compile this file into WebAssembly file
-O3 is the level of code optimization. 3 is high
-o index.js Compiler will create this JavaScript file so we can add it to the web page.


This compiles my code and creates index.wasm and index.js files.


    By default IIS does not serve wasm files, you need to add Wasm MimeType to the IIS settings. You can do that by editing your web.config. Just add the following <staticContent> tag into your <system.webserver> tag


      From this point, things should go easier, all we need to do is to add a script tag and reference the index.js file created by the compiler. Also I need to add the index.wasm file into my project, it should be available just like any other contents of my web application in my IIS server.


       Index.js is the JavaScript file created by the compiler. This file makes the connection between your browser and webAssembly.  I have copied the wasm file into my project's root. As you can see, I have created a button on this page. Application is going to call the C++ function when button is clicked. When page is loaded I see the following text in my browser's console.  This text comes from the main() function of C++



     When I click on Get Temperature button, application calls my C++ code and returns the value.


    I just executed C++ code on my web application. It doesn't do that much but it works. Microsoft has been working on adding C# to WebAssembly. Probably, you will hear more about WebAssembly when C# is ready but today it's already working with with C and C++
   
    I tried to connect to my local SQL Server from the client side by using WebAssembly. In the following scenerio, User connects to the SQL Server directly from the WebAssembly without any IIS server side call. I execute the "SELECT @@VERSION" statement and return its value to the client side.

string CallSqlServer() {
#define SQL_RESULT_LEN 240
#define SQL_RETURN_CODE_LEN 1000

 SQLHANDLE sqlConnHandle;
 SQLHANDLE sqlStmtHandle;
 SQLHANDLE sqlEnvHandle;
 SQLWCHAR retconstring[SQL_RETURN_CODE_LEN];

 sqlConnHandle = NULL;
 sqlStmtHandle = NULL;

 if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlEnvHandle))
  goto COMPLETED;
 if (SQL_SUCCESS != SQLSetEnvAttr(sqlEnvHandle, SQL_ATTR_ODBC_VERSION, 
(SQLPOINTER)SQL_OV_ODBC3, 0))
  goto COMPLETED;
 if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlEnvHandle, &sqlConnHandle))
  goto COMPLETED;
 switch (SQLDriverConnect(sqlConnHandle, NULL, (SQLWCHAR*)L"DRIVER={SQL SERVER};
 SERVER=servername;DATABASE=master;Trusted=true;",
  SQL_NTS, retconstring, 1024, NULL, SQL_DRIVER_NOPROMPT)) {
 case SQL_SUCCESS:
  break;
 case SQL_SUCCESS_WITH_INFO:
  break;
 case SQL_INVALID_HANDLE:
  goto COMPLETED;
  break;
 case SQL_ERROR:
  goto COMPLETED;
  break;
 default:
  break;
 }
 if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlConnHandle, &sqlStmtHandle))
  goto COMPLETED;
 if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT @@VERSION",
 SQL_NTS)) {
  goto COMPLETED;
 }
 else {
  SQLCHAR sqlVersion[SQL_RESULT_LEN];
  SQLINTEGER ptrSqlVersion;
  while (SQLFetch(sqlStmtHandle) == SQL_SUCCESS) {
   SQLGetData(sqlStmtHandle, 1, SQL_CHAR, sqlVersion, 
SQL_RESULT_LEN, &ptrSqlVersion);
   return sqlVersion;
  } }
COMPLETED:
 SQLFreeHandle(SQL_HANDLE_STMT, sqlStmtHandle);
 SQLDisconnect(sqlConnHandle);
 SQLFreeHandle(SQL_HANDLE_DBC, sqlConnHandle);
 SQLFreeHandle(SQL_HANDLE_ENV, sqlEnvHandle); 
 return "Error";
}

     Here is the result. I just executed a Select Statement in SQL Server from html page without touching any server side code or ActiveX code. Let's digest what just happened here. IDream comes true of a programmer or a nightmare of a DBA? 


4 comments:

  1. JavaScript and programming is a important part to make a good design. Here you provided good c++ programming language script which should helpful for computer engineering students and as well as designers. Thanks for sharing. To see nursing resume sample look here http://www.rnresume.net/well-written-sample-new-grad-nursing-resume/

    ReplyDelete
  2. Very informative blog. By following step by step procedure we can conquer many wars. These designs in c++ progaming can help you to maintain data in organize way so read more about it ad have best one.

    ReplyDelete
  3. Would you mind sharing your code ? I am not super familiar with C++ and I am trying to figure out how you did load the SqlServer driver.

    ReplyDelete