Nano Hash - криптовалюты, майнинг, программирование

Почему первый символ wchar_t* стирается при передаче компоненту WinRT?

У меня есть класс ref в компоненте WinRT:

namespace WinRTComponent
{
    public ref class Class1 sealed
    {
    public:
        Class1();

        void MyMethod(wchar_t* wcharPtr)
        {
            // Do nothing.
        }
    };
}

У меня также есть приложение Windows Store C++ XAML, в котором есть ссылка на компонент WinRT. В моем приложении я запускаю следующий код:

std::wstring str = L"Some text.";
const wchar_t* strPtr = str.data();

WinRTComponent::Class1^ class1 = ref new WinRTComponent::Class1();

wchar_t firstCharBefore = strPtr[0]; // It is 'S', correctly.

class1->MyMethod(const_cast<wchar_t*>(strPtr));

wchar_t firstCharAfter = strPtr[0]; // It is 0! Why?

Когда я передаю указатель wchar_t* публичному методу компонента WinRT, первый символ строки стирается и заменяется на 0.

Что является причиной этого? Это ожидаемое поведение или ошибка?


  • Я бы не ожидал ничего разумного, если бы отказался от константной правильности... 13.06.2013
  • Но я не могу сделать так, чтобы подпись компонента принимала const wchar_t*, потому что это, по-видимому, не поддерживается компонентами WinRT (ошибка сборки: C4400: 'const wchar_t' : const/volatile qualifiers on this type are not supported). 13.06.2013
  • Можете ли вы попробовать std::vector<wchar_t> strCpy(str.begin(), str.end()), а затем вы можете передать адрес первого элемента как &strCpy[0]. Это должно устранить необходимость в const_cast, и мы сможем увидеть, является ли это источником вашей ошибки. 13.06.2013
  • Строки никогда не были проблемой в C++, шутка в том, что каждый программист придумывает свой собственный строковый тип. Как и в WinRT, вам нужно будет использовать Platform::String. Преобразование туда и обратно в std::wstring описано в этой справочной статье 13.06.2013
  • Я могу просто преобразовать wstring в Platform::String, и это работает правильно, но это копирует строку в новый экземпляр каждый раз, когда я вызываю этот компонент, чего я хотел бы избежать. Вот почему я просто хотел бы передать указатель. 13.06.2013
  • Дэйв, то же самое происходит с скопированным вектором, его первый элемент устанавливается равным нулю (но остальные элементы остаются нетронутыми). 13.06.2013

Ответы:


1

Я думаю, это происходит из-за того, что общедоступный метод void MyMethod(wchar_t* wcharPtr) для ref class не является функцией, которая принимает входную строку, это функция, имеющая выходной параметр wchar_t. Другими словами, для WinRT MyMethod есть функция, возвращающая 16-битный символ. Итак, я предполагаю, что механизм WinRT ABI либо скрывает значение, прежде чем передать его MyMethod, либо обнаруживает, что ваша реализация MyMethod никогда не присваивает ему значение, и генерирует код, который присваивает ему значение по умолчанию.

Ключевым выводом является то, что параметры указателя в общедоступном методе ref class означают вывод, а не ввод указателя. Указатели не могут пересекать границу ABI, это могут делать только типы WinRT. Тип C++ wchar_t сопоставляется с 16-разрядным символьным типом WinRT, так что это нормально, а параметры указателя — это способ, которым C++/CX реализует выходные параметры WinRT, потому что это наиболее естественный способ для C++ возвращать данные через параметры.

Чтобы написать общедоступный метод компонента, который принимает строковое входное значение в C++/CX, вы должны использовать Platform::String^ в качестве типа аргумента. Если вы вызываете эту функцию из C++/CX, вы можете избежать создания копии, передав StringReference:

WinRTComponent::Class1^ class1 = ref new WinRTComponent::Class1();
class1->MyMethod(Platform::StringReference(strPtr));

Если вы это сделаете, вы обнаружите, что вызов Data() на String^ внутри MyMethod дает вам тот же strPtr, который вы передали.

См. раздел «StringReference» документа Документацию по строкам C++/CX для получения дополнительной информации.

18.07.2013
  • Вы правы, спасибо. С тех пор я получил еще один ответ на форумах Microsoft: первый символ wchart стирается при передаче в компонент winrt#ff47f0a8-7e7f-4ee1-b501-783bc05c12e9" rel="nofollow noreferrer">social.msdn.microsoft.com /Forums/windowsapps/en-US/ Правила COM говорят, что параметры должны быть стабилизированы до нуля. если между ними есть уровень маршалинга, он может реализовать это для вас. 03.08.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..