0

Is it possible to parse json data with the WinAPI windows.data.json.h header file?

I have looked at various sources of documentation such as:

And I have tried to get it to parse this simple file:

{"main":"Hello World"}

I got about as far as this:

#include <windows.data.json.h>

int main() {

    JsonObject(Parse("{\"main\":\"Hello World\"}"));

    return 0;
}

Before an error was thrown:

'JsonObject' undefined; assuming extern returning int
'Parse' undefined; assuming extern returning int

I also tried static JsonObject Parse("{\"main\":\"Hello World\"}"));but that failed also.

So this is obviously not the way to do it.

Can someone help get me started and explain how to parse that json with json.h?

I also found this but it is for C#.

9
  • 2
    That is for managed C++ or WinRT, not C. Commented Jun 3, 2018 at 0:04
  • 1
    I use this. Works like a charm. Commented Jun 3, 2018 at 5:43
  • 1
    Heads-up: for Unicode builds, you'll need to slip this in somewhere: #define json_char TCHAR. Enjoy. Commented Jun 3, 2018 at 8:29
  • 1
    @RetiredNinja: UWP is native code, with an API surface accessible to native code. It's unclear, why people keep spreading the fallacy, that UWP were somehow related to managed code. It isn't, in any way. No need to drag in the .NET Core dependency at all to consume the UWP API. Now that UWP is based on COM, it is of course accessible from C, even if a bit tedious. So the answer is: Yes, it is callable from C, but if you have to ask, it's probably not for you. Commented Jun 3, 2018 at 11:35
  • 1
    @IInspectable You're right, it is technically possible, but not entirely practical. It would be much easier to use an existing json library meant for use with C. Commented Jun 3, 2018 at 20:47

2 Answers 2

2

@Simon,

I don't know how you set up your project, but all of the 'windows.' headers (windows.data.json or windows.data.text) are for applications using the UWP (Universal Windows Platform) API. So they will only work if your making a UWP API application.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah turned out it wasn't possible unfortunately :(
But it is possible. Just call RoInitialize ActivateInstance, passing in HSTRING of RuntimeClass_Windows_Data_Json_JsonObject (use WindowsCreateReferenceString), It will give you a base interface (IInspectable) to a class instance, which you can QueryInterface for various interfaces like __x_ABI_CWindows_CData_CJson_CIJsonObjectVtbl. You can use those interfaces perfectly well from C, no problem. It's just that all the symbol names are long to type, seeing as they're all prefixed with namespace information. But no biggy, it's basically the same as COM, with a few caveeats like HSTRING.
0

As the Windows Runtime is built on top of COM, you can use those interfaces perfectly well from plain, native C. It is basically the same as COM, with a few caveats like class ids are actually name strings, and strings have to be wrapped up as a HSTRING. It is true that most symbol names may be quite long, as they hold namespace information. But you could typedef them to your liking, or use a macro to define a shorter name. All in all it's no biggy.

Here is an example I just made for you, in plain C. I compiled it with Visual C compiler and it ran just fine.

``` c

#include <roapi.h>
#include <windows.data.json.h>
#include <stdio.h>

#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "runtimeobject.lib")

static BOOL init_windows_runtime(void);

static void quit_windows_runtime(void);

static BOOL create_windows_runtime_class_instance(
    PCWSTR class_id, REFIID riid, void** object);

static const IID IID___x_ABI_CWindows_CData_CJson_CIJsonObject = 
{
    0x064e24dd, 0x29c2, 0x4f83, {0x9a, 0xc1, 0x9e, 0xe1, 0x15, 0x78, 0xbe, 0xb3}
};

static BOOL init_windows_runtime(void)
{
    HRESULT hr = RoInitialize(RO_INIT_MULTITHREADED);
    return SUCCEEDED(hr);
}

static void quit_windows_runtime(void)
{
    RoUninitialize();
}

static BOOL create_windows_runtime_class_instance(
    PCWSTR class_id, REFIID riid, void** object)
{
    HRESULT        hr;
    HSTRING_HEADER class_id_header;
    HSTRING        class_id_string;
    IInspectable*  inspectable;

    *object = NULL;

    hr = WindowsCreateStringReference(
        class_id, (UINT32)wcslen(class_id),
        &class_id_header, &class_id_string);
    
    if (FAILED(hr))
    {
        return FALSE;
    }

    hr = RoActivateInstance(class_id_string, &inspectable);
    if (FAILED(hr))
    {
        return FALSE;
    }

    hr = inspectable->lpVtbl->QueryInterface(inspectable, riid, object);
    inspectable->lpVtbl->Release(inspectable);

    return SUCCEEDED(hr);
}

int main(int argc, char* argv[])
{
    __x_ABI_CWindows_CData_CJson_CIJsonObject* json_object;

    if (!init_windows_runtime())
    {
        return EXIT_FAILURE;
    }

    if (!create_windows_runtime_class_instance(
        RuntimeClass_Windows_Data_Json_JsonObject,
        &IID___x_ABI_CWindows_CData_CJson_CIJsonObject,
        &json_object))
    {
        quit_windows_runtime();
        return EXIT_FAILURE;
    }

    /* And there it is, your COM interface: json_object                       */
    /* You can set values using the json_object->lpVtbl->SetNamedValue method */
    /* You can get values using one of the json_object->lpVtbl->Get* methods  */
    /* Keep in mind that most of the parameters are Windows Runtime objects   */
    /* as well, meaning you have to do the above for them. Wrap up their      */
    /* class id/name in a HSTRING reference, create instance which gives an   */
    /* IInspectable interface, query that interface for desired interface.    */
    /* The header file windows.data.json.h contains all the necessary info.   */

    /* An example method call: */
    {
        HRESULT    hr;
        TrustLevel trust_level;
        
        hr = json_object->lpVtbl->GetTrustLevel(json_object, &trust_level);
        if (SUCCEEDED(hr))
        {
            printf("Trust level: ");
            switch (trust_level)
            {
                case BaseTrust:    { printf("Base\n");     break; }
                case PartialTrust: { printf("Partial\n");  break; }
                case FullTrust:    { printf("Fulll\n");    break; }
                default:           { printf("Unknown?\n"); break; }
            }
        }
    }

    json_object->lpVtbl->Release(json_object);

    quit_windows_runtime();
    return EXIT_SUCCESS;
}
```

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.