Преобразование пустоты* к станд.:: строка

Отмеченный ответ не выполнен на 100%, так как он игнорирует любой IContractResolver, который может быть зарегистрирован, например CamelCasePropertyNamesContractResolver и т. д.

Также возврат false для can convert может предотвратить другие случаи пользователя, поэтому я изменил его на return objectType.GetCustomAttributes(true).OfType().Any();

Вот обновленная версия: https://dotnetfiddle.net/F8C8U8

Я также удалил необходимость установить JsonProperty на свойство, как показано в ссылке.

Если по какой-либо причине ссылка выше умирает или взрывается, я также включаю следующий код:

public class JsonPathConverter : JsonConverter
    {
        /// 
        public override object ReadJson(
            JsonReader reader,
            Type objectType,
            object existingValue,
            JsonSerializer serializer)
        {
            JObject jo = JObject.Load(reader);
            object targetObj = Activator.CreateInstance(objectType);

            foreach (PropertyInfo prop in objectType.GetProperties().Where(p => p.CanRead && p.CanWrite))
            {
                JsonPropertyAttribute att = prop.GetCustomAttributes(true)
                                                .OfType()
                                                .FirstOrDefault();

                string jsonPath = att != null ? att.PropertyName : prop.Name;

                if (serializer.ContractResolver is DefaultContractResolver)
                {
                    var resolver = (DefaultContractResolver)serializer.ContractResolver;
                    jsonPath = resolver.GetResolvedPropertyName(jsonPath);
                }

                if (!Regex.IsMatch(jsonPath, @"^[a-zA-Z0-9_.-]+$"))
                {
                    throw new InvalidOperationException($"JProperties of JsonPathConverter can have only letters, numbers, underscores, hiffens and dots but name was ${jsonPath}."); // Array operations not permitted
                }

                JToken token = jo.SelectToken(jsonPath);
                if (token != null && token.Type != JTokenType.Null)
                {
                    object value = token.ToObject(prop.PropertyType, serializer);
                    prop.SetValue(targetObj, value, null);
                }
            }

            return targetObj;
        }

        /// 
        public override bool CanConvert(Type objectType)
        {
            // CanConvert is not called when [JsonConverter] attribute is used
            return objectType.GetCustomAttributes(true).OfType().Any();
        }

        /// 
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var properties = value.GetType().GetRuntimeProperties().Where(p => p.CanRead && p.CanWrite);
            JObject main = new JObject();
            foreach (PropertyInfo prop in properties)
            {
                JsonPropertyAttribute att = prop.GetCustomAttributes(true)
                    .OfType()
                    .FirstOrDefault();

                string jsonPath = att != null ? att.PropertyName : prop.Name;

                if (serializer.ContractResolver is DefaultContractResolver)
                {
                    var resolver = (DefaultContractResolver)serializer.ContractResolver;
                    jsonPath = resolver.GetResolvedPropertyName(jsonPath);
                }

                var nesting = jsonPath.Split('.');
                JObject lastLevel = main;

                for (int i = 0; i < nesting.Length; i++)
                {
                    if (i == nesting.Length - 1)
                    {
                        lastLevel[nesting[i]] = new JValue(prop.GetValue(value));
                    }
                    else
                    {
                        if (lastLevel[nesting[i]] == null)
                        {
                            lastLevel[nesting[i]] = new JObject();
                        }

                        lastLevel = (JObject)lastLevel[nesting[i]];
                    }
                }
            }

            serializer.Serialize(writer, main);
        }
    }

26
задан Lewis 19 June 2010 в 23:51
поделиться

4 ответа

Вам просто нужно динамически выделить его (потому что он, вероятно, должен пережить объем, в котором вы его используете), а затем преобразовать его туда и обратно:

// Cast a dynamically allocated string to 'void*'.
void *vp = static_cast<void*>(new std::string("it's easy to break stuff like this!"));

// Then, in the function that's using the UserEvent:
// Cast it back to a string pointer.
std::string *sp = static_cast<std::string*>(vp);
// You could use 'sp' directly, or this, which does a copy.
std::string s = *sp;
// Don't forget to destroy the memory that you've allocated.
delete sp;
22
ответ дан 28 November 2019 в 07:36
поделиться

На основании вашего комментария «Я имел в виду преобразовать то, на что указывает пустота * (которая является строкой), в строку».

Предполагая, что у вас есть это:

std::string str = ...;
void *ptr = &str;

Вы можете просто привести обратно к строке:

std::string *pstr = static_cast<std::string *>(ptr);

Заметьте, что вы должны убедиться, что ptr действительно указывает на std::string. Если вы ошибаетесь и это указывает на что-то еще, это приведет к неопределенному поведению.

7
ответ дан R Samuel Klatchko 28 November 2019 в 07:36
поделиться

Если void является const char *, то вы можете просто вызвать с ним конструктор std :: string, т.е.

const char* cakes = something;
std::string lols = std::string(cakes);
1
ответ дан Puppy 28 November 2019 в 07:36
поделиться

Если вы пытаетесь отформатировать адрес как текст, вы можете использовать строковый поток :

std::stringstream strm;
strm << ptr;
std::string str = strm.str(); 

// str will now have something like "0x80004567"

Если это не то, что вас интересует, уточните свой вопрос.

5
ответ дан 28 November 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: