ANSI C API

C++ API versus C API

One of the main problems with our C++ API is that it uses the STL throughout. While this is very useful to some, the convenience comes at a price: incompatibility with any MSVC build except the one it was built with.

Our ANSI C Wrapper has no such problem— if you use our C API, you can use the Awesomium DLL with any MSVC build (including VS2010) as well as mix-and-match debug and release builds (which is very useful, considering WebViews in our debug build tend to assert upon a variety of innocuous HTML/JS errors).

Using the C API

To use our new C API, simply add the following header to your application:

#include <Awesomium/awesomium_capi.h>

To start off, we'd recommend looking at some of the following functions:

awe_webcore_initialize()
awe_webcore_initialize_default()
awe_webcore_shutdown()
awe_webcore_create_webview()
awe_webview_load_url()
awe_webview_render()
awe_webview_destroy()

Avoiding Memory Leaks

To avoid memory leaks, there is one major rule that you must follow in our C API regarding ownership of returned objects: if a function returns a regular pointer to an instance, you must destroy the instance using the relevant method.

Otherwise, if a function returns a const pointer to an instance, you should NOT destroy it (ownership is retained by Awesomium).

For example, you must destroy all strings you create in Awesomium:

 awe_string* str = awe_string_create_from_ascii("Hello", strlen("Hello"));

 // Use the string somewhere... then destroy it when we are done:

 awe_string_destroy(str);

But you should NOT destroy certain strings returned from certain methods:

 const awe_string* str = awe_webcore_get_base_directory();

 // We do not need to destroy this string: when a function returns
 // a const pointer in Awesomium, it means ownership is retained by
 // Awesomium and the instance will be destroyed automatically later.

Full Code Example: HelloAwesomium with C API

Here's a full code example of our "HelloAwesomium" sample re-written using our C API (v1.6.2):

#include <Awesomium/awesomium_capi.h>
#include <iostream>
#if defined(__WIN32__) || defined(_WIN32)
#include <windows.h>
#elif defined(__APPLE__)
#include <unistd.h>
#endif

// Various macro definitions
#define WIDTH   512
#define HEIGHT  512
#define URL "http://www.google.com"
#define SLEEP_MS    50

// Our main program
int main()
{
    // Create our WebCore singleton with the default options
    awe_webcore_initialize_default();

    // Create a new WebView instance with a certain width and height, using the 
    // WebCore we just created
    awe_webview* webView = awe_webcore_create_webview(WIDTH, HEIGHT, false);

    // Create our URL string
    awe_string* url_str = awe_string_create_from_ascii(URL, strlen(URL));

    // Load a certain URL into our WebView instance
    awe_webview_load_url(webView, url_str, awe_string_empty(), 
                            awe_string_empty(), awe_string_empty());

    // Destroy our URL string
    awe_string_destroy(url_str);

    std::cout << "Page is now loading..." << std::endl;;

    // Wait for our WebView to finish loading
    while(awe_webview_is_loading_page(webView))
    {
        // Sleep a little bit so we don't consume too much CPU while waiting 
        // for the page to finish loading.
#if defined(__WIN32__) || defined(_WIN32)
        Sleep(SLEEP_MS);
#elif defined(__APPLE__)
        usleep(SLEEP_MS * 1000);
#endif

        // We must call WebCore::update in our update loop.
        awe_webcore_update();
    }

    std::cout << "Page has finished loading." << std::endl;

    // Get our rendered buffer from our WebView. All actual rendering takes 
    // place in our WebView sub-process which passes the rendered data to our 
    // main process during each call to WebCore::update.
    const awe_renderbuffer* renderBuffer = awe_webview_render(webView);

    // Make sure our render buffer is not NULL-- WebView::render will return
    // NULL if the WebView process has crashed.
    if(renderBuffer != NULL)
    {
        // Create our filename string
        awe_string* filename_str = awe_string_create_from_ascii("./result.jpg", 
                                                        strlen("./result.jpg"));

        // Save our RenderBuffer directly to a JPEG image
        awe_renderbuffer_save_to_jpeg(renderBuffer, filename_str, 90);

        // Destroy our filename string
        awe_string_destroy(filename_str);

        std::cout << "Saved a render of the page to 'result.jpg'." << std::endl;

        // Open up the saved JPEG
#if defined(__WIN32__) || defined(_WIN32)
        system("start result.jpg");
#elif defined(__APPLE__)
        system("open result.jpg");
#endif
    }

    // Destroy our WebView instance
    awe_webview_destroy(webView);

    // Destroy our WebCore instance
    awe_webcore_shutdown();

    return 0;
}

AwesomiumSharp

Our .NET wrapper, AwesomiumSharp, was built using the C API so if you use it, you automatically get all of the above.