Skip to content

Using in Unreal Engine - handling custom types conversion #495

Description

@danielkcz

Hi. I come from a JavaScript world where working with JSON is total breeze. We are currently working on a game using Unreal Engine 4 and we need to develop custom save system using JSON format so it can be read using Javascript somewhere else.

I kinda like approach of this library as its syntax is similar to what I am used to from JS. Sadly me as total rookie to C++ I am struggling with this a lot. I would like to make some arbitrary conversions from Unreal types to ones supported by this library.

For example here is a header file for FString type. Somewhere else I've found what I need to do for conversion to std::string so I've tried to add following

namespace nlohmann {
	template <typename T>
	struct adl_serializer<FString> {
		static void to_json(json& j, const FString value) {
			j = TCHAR_TO_UTF8(*value)
		}
	};
}

However this is failing compilation with this error. I am totally clueless what that means. Can you please help?

error C3211: 'nlohmann::adl_serializer<FString,void>': explicit specialization is using partial specialization syntax, use template <> instead
note: see declaration of 'nlohmann::adl_serializer<FString,void>'

Activity

  1. nlohmann commented on Mar 11, 2017

    @nlohmann
    Owner

    I haven't tried it, but it should be sufficient to define a to_json function in the namespace of FString. In the header, I did not find a namespace, so it should be sufficient to define

    void to_json(json& j, const person& p) {
        j = TCHAR_TO_UTF8(*value);
    }

    (I just copied the j = TCHAR_TO_UTF8(*value); from your example).

    Then you should be able to execute for an FString object f: json j = f;.

  2. theodelrieu commented on Mar 11, 2017

    @theodelrieu
    Contributor

    What you need to do is to remove the typename T and it will work:

    template <>
    struct adl_serializer<FString> { ... };
  3. danielkcz commented on Mar 11, 2017

    @danielkcz
    Author

    @nlohmann I don't understand how that could work. How it can know to use global to_json function for FString?

    @theodelrieu Tried that and now I am getting...

    error C2908: explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been instantiated
    with
    [
    T=FString
    ]
    error C2766: explicit specialization; 'nlohmann::adl_serializer<T,void>' has already been defined
    with
    [
    T=FString
    ]

  4. theodelrieu commented on Mar 11, 2017

    @theodelrieu
    Contributor

    For types that belong to you, the free function is the best approach usually, however for those which are not in your namespaces that' s not really intended.

    I think that error means that you should put this piece of code at the very top of your file, because adl_serializer is instantiated when you do this:

    my_type mt;
    // adl_serializer<my_type> gets instantiated here
    json j = mt; 

    If you don't put your specialization before , you get that error message.

  5. danielkcz commented on Mar 11, 2017

    @danielkcz
    Author

    Ok, looks like that this actually works...

    void to_json(json& j, const FString& value) {
    	j = TCHAR_TO_UTF8(*value);
    }

    However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

    LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

    json result;
    FString test = TEXT("MyTest");
    result["key"] = test;
    
    UE_LOG(LogTemp, Warning, TEXT("JSON %s"), result.dump().c_str());

    I am not entirely sure I got that conversion to std::string right. Here is a source of the information: https://wiki.unrealengine.com/String_Conversions:_FString_to_FName,_FString_to_Int32,_Float_to_FString

    Also I had to use c_str() on the dump result as the UE_LOG macro does not recognize string_t. That last argument of UE_LOG is VarArgs

  6. theodelrieu commented on Mar 11, 2017

    @theodelrieu
    Contributor

    Since FString is defined in the global namespaces, this is much more easier indeed.

    Edit: about the conversion , I never used unreal, I don't think I can be of any help here...

  7. nlohmann commented on Mar 11, 2017

    @nlohmann
    Owner

    @FredyC I am also not an expert. To make sure, you could change the function to

    void to_json(json& j, const FString& value) {
        j = std::string(TCHAR_TO_UTF8(*value));
    }

    and then try:

    json result;
    FString test = TEXT("MyTest");
    result["key"] = test;
    
    std::cout << result << std::endl;

    The first change makes the conversion to a std::string explicit. The second string asks for a serialization without relying on the behavior of the UE_LOG function.

  8. danielkcz commented on Mar 11, 2017

    @danielkcz
    Author

    Well first change did not help and sadly it's not possible to use std::cout as there is no way to read output from it. The whole thing is executed from within Unreal Editor and there is no access to regular output.

    Anyway, I will try to figure that out on side of UE. Thanks for help!

  9. nlohmann commented on Mar 11, 2017

    @nlohmann
    Owner

    You're welcome. I shall close this issue. But it would be great if you could share your further experience with the library and UE.

  10. rrafis commented on Jan 17, 2019

    @rrafis

    Ok, looks like that this actually works...

    void to_json(json& j, const FString& value) {
    	j = TCHAR_TO_UTF8(*value);
    }

    However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

    LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

    @FredyC, have you found any solution with this?

  11. danielkcz commented on Jan 17, 2019

    @danielkcz
    Author

    @rrafis Sorry, I don't remember really, I've left Unreal Engine world shortly after this issue.

  12. kigbariom commented on Sep 17, 2019

    @kigbariom

    Ok, looks like that this actually works...

    void to_json(json& j, const FString& value) {
    	j = TCHAR_TO_UTF8(*value);
    }

    However when I am trying to dump that JSON now, I am getting bunch of japanese characters :)

    LogTemp:Warning: JSON ≻敫≹∺祍敔瑳索촀췍췍췍췍췍췍췍Ꭰ띂Ȳ

    @FredyC, have you found any solution with this?

    UE_LOG_UTF8 will fix that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions