WNetAddConnection2
C++/CLI を使用しており、Windows ネットワークから関数を呼び出したいと考えています。
まず、C++/CLI が自分の仕事に適した言語ではないことはわかっていますが、今のところそれを変更する可能性はなく、代わりに C# を使用しています。
問題は、この関数が wchar_t* を受け取るため、System::String^ を wchar_t* に変換する必要があることです。
解決策 1): を使用pin_ptr
しPtrToSTringChars
、vcclr.h
解決策 2) から: を使用しますStringToHGlobalUni
。(タイトルはStringHToGlobalAnsi
、より多くの人がそれを検索しているため、この投稿を見つけて回答が早くなる可能性があることを示しています)。
両方のソリューションが機能することがわかりました。しかし、#1はそうではありません。CWNetShare
次のコンストラクターを使用 して、WNet 関数を ref クラスに入れました。
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());
}
};
再び、コンストラクターに含まれる winformm_oManaged = gcnew CManaged;
です。後で m_oManaged にアクセスする場合、m_oManaged が移動されていなければ問題ありませんm_wszPinned
。
しかし、GCした後、それはナンセンスを示しています。しかし、 m_wsznothing はその値を保持するため、問題でwchar_t*
はなく、 pin_ptr の問題です。のアドレスm_oManaged
は変更されましたが、 のアドレスはm_wszPinned
同じであるのに、値が失われるのはなぜですか?
ここで何がうまくいかないのですか?
それでは、 pin_ptr と PtrToSTringChars には用途がありますか?
私は今、マーシャリングを使用しています。