How do I convert a std::string to System.String in C++ with Il2CppInspector?

1.1k views Asked by At

I am using Il2CppInspector to generate scaffolding for a Unity game. I am able to convert System.String (app::String in Il2CppInspector) to std::string using the functions provided below.

How would I reverse this process; how do I convert a std::string to System.String?

helpers.cpp

    // Helper function to convert Il2CppString to std::string
    std::string il2cppi_to_string(Il2CppString* str) {
        std::u16string u16(reinterpret_cast<const char16_t*>(str->chars));
        return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(u16);
    }
    // Helper function to convert System.String to std::string
    std::string il2cppi_to_string(app::String* str) {
        return il2cppi_to_string(reinterpret_cast<Il2CppString*>(str));
    }

In short, I am looking for a function that takes in a std::string and returns an app::String

    // Helper function to convert std::string to System.String
    app::String string_to_il2cppi(std::string str) {
        // Conversion code here
    }
2

There are 2 answers

5
BullyWiiPlaza On BEST ANSWER

The accepted answer is actually wrong, there is no size parameter and copying stops at the first null byte (0x00) according to the MSDN documentation.

The following code fixes these problems and works correctly:

app::String* string_to_il2cppi(const std::string& string)
{
    const auto encoding = (*app::Encoding__TypeInfo)->static_fields->utf8Encoding;

    const auto managed_string = app::String_CreateStringFromEncoding((uint8_t*)&string.at(0), string.size(), encoding, nullptr);

    return managed_string;
}

A quote from djkaty:

To create a string, you cannot use System.String‘s constructors – these are redirected to icalls that throw exceptions. Instead, you should use the internal Mono function String.CreateString. This function has many overloads accepting various types of pointer and array; an easy one to use accepts a uint16_t* to a Unicode string and can be called as follows [...]

0
UnAlpha On

Export Il2CppInspector with all namespaces, which will give you access to Marshal_PtrToStringAnsi.

app::String* string_to_il2cppi(std::string str) {
    return app::Marshal_PtrToStringAnsi((void*)&str, NULL);
}

Limitation: do not attempt to convert a string with null terminators inside of them example:

std::string test = "Hello\0world";

Use BullyWiiPlaza's solution if this is an issue for you.