C ++ / Cli Проверка сетевого подключения - PullRequest
0 голосов
/ 17 марта 2019

вот код

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient Client = gcnew System::Net::Sockets::TcpClient ("www.google.com", 80);

            Client.Close ();

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

Я пытаюсь проверить подключение к сети, нашел этот код в интернете и немного изменил его для работы с моим проектом, но он говорит

no suitable user-defined conversion from "System::Net::Sockets::TcpClient ^" to "System::Net::Sockets::TcpClient" exists     Project1   33  

И я довольно новичок в этом, поэтому я не знаю, что делаю.

1 Ответ

1 голос
/ 20 марта 2019

В C ++ / CLI вы должны объявлять ссылки на объекты с завершающим ^, аналогично оператору * для собственных указателей.Более того, методы для ссылок чаще всего вызываются с помощью оператора ->.Попробуйте это:

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient^ Client = gcnew System::Net::Sockets::TcpClient ("www.google.com", 80);

            Client->Close ();

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

РЕДАКТИРОВАТЬ: Как правильно указывает Ганс Пассант, есть еще одна проблема с этим кодом, которая не является синтаксической.Поскольку TcpClient реализует IDisposable, а вызов Close() находится в блоке try, ссылка на объект никогда не удаляется в случае исключения.Поэтому вызов Close() должен находиться за пределами блока try.

Однако C ++ / CLI предлагает гораздо лучший способ решения этой проблемы, который называется «семантика стека».Это эквивалентно утверждению C # using.Он используется так:

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient Client (L"www.google.com", 80);

            // Dispose() or Close() not needed anymore

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

Так что ссылка TcpClient объявлена ​​как локальная переменная.Но на самом деле он будет создан в куче, и как только переменная Client выйдет из области видимости, Client.Dispose () будет вызван автоматически.Следовательно, вызов Close() вообще не нужен, и объект удаляется должным образом, независимо от того, выбрасывается ли исключение или метод завершается нормально.

Спасибо Хансу Пассанту за указание на это.Семантика стека для IDispose является хорошей практикой в ​​C ++ / CLI.

Обратите внимание, что я изменил литерал String в конструкторе на L"...".Это также хорошая практика, потому что пропуск «L» приведет к проблемам, как только символы Unicode будут выходить за пределы 8-битного диапазона.

...