Как решить, что «IServiceProvider» неоднозначен при использовании «wininet» и «windows.h»?

Я пытаюсь проверить, существует ли интернет-соединение, используя функцию InternetCheckConnection в wininet.

Вот мой CheckerClass:, который обрабатывает процесс проверки.

#pragma once
#include <Windows.h>
#include <wininet.h>
#pragma comment(lib,"wininet.lib")
#include <String>

public ref class CheckerClass
{
public:
    static std::string hasInternet() {
        bool bConnect = InternetCheckConnection(L"https://www.google.com", FLAG_ICC_FORCE_CONNECTION, 0);
        if (bConnect){
            return "Has Internet!";
        }else{
            return "No Internet!";
        }
    }
};

Но я получаю следующую ошибку, и я не могу ее решить.

Error (active)  E1986   an ordinary pointer to a C++/CLI ref class or interface class is not allowed
Error (active)  E0266   "IServiceProvider" is ambiguous
Error   C3699   '*': cannot use this indirection on type 'IServiceProvider' 

После поиска я нашел эту банку из-за использования using namespace System, но у меня нет этого в классе выше.

Однако у меня есть следующее из основного класса, где я использую вышеуказанный класс.

#pragma once
#include<string>
#include "CheckerClass.h"
namespace CppCLRWinformsProjekt {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using std::string;

    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:

        CheckerClass checkerClass;
        
        Form1(void)
        {
            InitializeComponent();
            string result = checkerClass.hasInternet();
            this->label_output->Text = gcnew System::String(result.c_str());
        }

    .....

Может ли кто-нибудь объяснить, что происходит и как я могу решить вышеуказанную проблему?

Это файлы .h, вы еще не нашли файл .cpp, который включает их. И содержит использование пространства имен System, что искажает объявления Windows.h. Одна очевидная ошибка, о которой вы должны получить диагностику, — это переменная checkerClass, которая должна быть объявлена ​​как CheckerClass^.

Hans Passant 24.12.2020 16:32

@HansPassant - думаю, у меня проблемы с классом.

user14352137 25.12.2020 06:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
1 002
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это потому, что using namespace System; конфликтует с именем в Windows.h,

Windows.h введено servprov.h косвенно. И servprov.h имеет такое определение: typedef interface IServiceProvider IServiceProvider; Среди них IServiceProvider конфликтует с IServiceProvider в пространстве имен System, вызывая неопределенность.

Решение состоит в том, чтобы использовать полное имя вместо пространства имен System, например System::IServiceProvider.

Можете ли вы рассказать мне больше об этом? Где я должен это сделать? Потому что я пытался удалить пространство имен, связанное с System, из основного класса, и все равно сталкивался с той же проблемой. Я пытался использовать System::IServiceProvider на CheckerClass и все еще получаю ту же проблему.

user14352137 24.12.2020 06:02

Вы можете попробовать закомментировать все using namespace System; При использовании IServiceProvider используйте вместо этого System::IServiceProvider. Есть еще одна возможность. Просмотрите включенные файлы, есть ли в подфайле два параметра пространства имен. Например, using namespace System;using namespace System::IO; Конфликт был вызван дублированием настроек в одном из включенных файлов.

Barrnet Chou 24.12.2020 09:14

Таким образом, конфликты произошли из-за того, что я неправильно инициализировал свой класс. Я немного запутался с h файлом и cpp файлом. Я думал, что концепция создания классов на C++ и Java одинакова. Спасибо!

user14352137 25.12.2020 06:05
Ответ принят как подходящий

Какой CheckerClass у вас? Классы обычно разбиваются на два файла. Это означает, что у вас должны быть CheckerClass.h и CheckerClass.cpp. Где этот код выше из этих двух файлов?

В любом случае, вот пример рабочего класса, основанного на вашем коде.

В вашем файле CheckerClass.h вы должны иметь;

#include <string>
#ifndef CHECKER_CLASS_H
#define CHECKER_CLASS_H
using std::string;
class CheckerClass {

private:
    //declare private variables here, if you need one.
public:

    CheckerClass(); 
    
    string hasInternet(); //The function
};
#endif

Затем реализация класса попадает в файл CheckerClass.cpp;

#include "CheckerClass.h"
#include "string"
#include "windows.h"
#include "wininet.h"
#pragma comment(lib,"wininet.lib")

CheckerClass::CheckerClass() {
    //initialize variable here if needed.
}

std::string CheckerClass::hasInternet() {
    bool bConnect = InternetCheckConnection(L"https://www.google.com", FLAG_ICC_FORCE_CONNECTION, 0);
    if (bConnect) {
        return "has Internet";
    }
    else {
        return "no internet";
    }
}

Теперь вы можете получить результат с помощью своего кода;

string result = checkerClass.hasInternet();
this->label_output->Text = gcnew System::String(result.c_str());

Это позволит избежать конфликтов и ошибок, с которыми вы столкнулись.

Таким образом, конфликты произошли из-за того, что я неправильно инициализировал свой класс. Я немного запутался с h файлом и cpp файлом. Я думал, что концепция создания классов на C++ и Java одинакова. Спасибо!

user14352137 25.12.2020 06:05

Другие вопросы по теме