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;
}
```
#define json_char TCHAR. Enjoy.