1

WNetAddConnection2C++/CLI を使用しており、Windows ネットワークから関数を呼び出したいと考えています。
まず、C++/CLI が自分の仕事に適した言語ではないことはわかっていますが、今のところそれを変更する可能性はなく、代わりに C# を使用しています。

問題は、この関数が wchar_t* を受け取るため、System::String^ を wchar_t* に変換する必要があることです。
解決策 1): を使用pin_ptrPtrToSTringCharsvcclr.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 CWNetShareWinform クラス コンストラクター (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 には用途がありますか?

私は今、マーシャリングを使用しています。

4

1 に答える 1