Я использую C++/CLI, и я хочу вызвать функцию WNetAddConnection2
из Windows Networking.
Во-первых, я знаю, что C++/CLI не является языком выбора для моей работы, но у меня нет возможности изменить это прямо сейчас и, например, вместо этого используйте C#.pin_ptr & PtrToStringChars против StringToHGlobalAnsi: Почему PtrToStringChars var потерял свою ценность?
Проблема в том, что эта функция принимает wchar_t *, поэтому мне нужно преобразовать System :: String^в wchar_t *.
Решение 1): использовать pin_ptr
и PtrToSTringChars
от vcclr.h
Решение 2): используйте StringToHGlobalUni
. (Название упоминает StringHToGlobalAnsi
, потому что больше людей ищут это, чтобы они могли найти этот пост, и это ответы быстрее).
Я выяснил, что оба решения работают. Но №1 на самом деле. Я поставил Wnet-функцию в исй класс CWNetShare
со следующим конструктором:
CWNetShare::CWNetShare (String^ i_sLocalDrive, ...) {
pin_ptr<const wchar_t> wszTemp;
wszTemp = PtrToStringChars(i_sLocalDrive);
m_wszLocalDrive = const_cast<wchar_t*>(wszTemp);
где m_wszLocalDrive
является частным CWNetShare
члена типа wchar_t*
.
Настоящая проблема: при вызове конструктора по m_oWNetShare = gcnew CWNetShare
из конструктора класса Winform (я знаю, C++/CLI и Winforms ...) все кажется прекрасным. Строка i_sLocalDrive
и другие преобразованы и назначены правильно. Но при доступе к m_oWNetShare
позже значения во всех переменных m_wsz ... теряются. Похоже, объект был перемещен GC.
Поэтому я сделал тест:
ref class CManaged {
public:
wchar_t* m_wszNothing;
wchar_t* m_wszPinned;
wchar_t* m_wszMarshal;
System::String^ m_sTest;
CManaged()
{
m_sTest = "Hello";
m_wszNothing = L"Test";
pin_ptr<const wchar_t> wszTemp;
wszTemp = PtrToStringChars(m_sTest);
m_wszPinned = const_cast<wchar_t*>(wszTemp);
m_wszMarshal = static_cast<wchar_t*>(System::Runtime::InteropServices::Marshal::StringToHGlobalUni (m_sTest).ToPointer());
}
};
Опять WinForm с m_oManaged = gcnew CManaged;
в конструктор. При доступе к m_oManaged позже, если m_oManaged не был перемещен, m_wszPinned
в порядке.
Но после GCing это проявляет ерунду. НО m_wsznothing сохраняет свою ценность, поэтому это не проблема wchar_t*
, а pin_ptr как-то. Адрес m_oManaged
изменился, но адрес m_wszPinned
тот же, так почему же тогда потеряно значение?
Что пошло не так?
Использует ли pin_ptr и PtrToSTringChars?
Я использую marshalling now, который работает.
Не забывайте называть 'FreeHGlobal()' в 'IntPtr', который возвращается из' StringToHGlobalUni() ', как описано в разделе [Как преобразовать систему :: String в стандартную строку] (http://msdn.microsoft. com/en-us/library/1b4az623.aspx) " – skst