Visual C ++ / CLI - CLR Class - LNK2020 Ошибка - как исправить? - PullRequest
3 голосов
/ 09 марта 2011

У меня есть проект, где я должен подключиться к библиотеке, основанной на C, и я не смог получить доступ к функциям из C # с помощью DLLImport.Я должен использовать проект, который является C ++ / CLI, основанным на поверхности этих функций для использования.(подробнее к этой истории, но не важно).

Я изучал C ++ более 10 лет назад, так что извините, если это кажется наивным.
В последний раз я купил несколько книг по реализации C ++ / CLI.год, и иметь некоторое представление о том, что происходит - я только копался в этих книгах для этого проекта.(Я был программистом в течение долгого времени).

Я подумал, что лучше начать небольшой пример проекта, чтобы ознакомиться с тем, что будет в нем участвовать, убедиться, что я смогу скомпилировать и т. Д. Я началпроект с использованием Visual Studio 2008 SP1;Visual C ++> CLR> Библиотека классов.В проекте - хочу использовать как управляемые, так и нативные из DLL.Так что используется ключ / clr.

Я использовал другие имена в реальном коде;но это очень и очень близко.(на данный момент нет других файлов или функций)

Заголовок:

//myWrapper.h
#pragma once
using namespace System;
namespace myWrapper {
  public ref class myWrappedService {
         myWrappedService();
         bool Connected(String ^user,String ^password,String ^domain);
  }
};

И реализация имеет это.

//myWrapper.cpp
//This is the main DLL file
#include "stdafx.h"
#include "myWrapper.h"
using namespace System;
public ref class myWrappedService
   {
      public:
            myWrappedService() {}
            bool Connected(String ^user,String ^password,String ^domain)
            {
               //just a simple result to start - no real functionality
               bool result = false;
               return result;
            }
   };

Это код -который компилируется, но получает ошибки компоновщика.

ошибка LNK2020: неразрешенный токен (06000002) myWrapper.myWrappedService :: Connected

фатальная ошибка LNK1120: 1 неразрешенная внешняя.

Это выглядело чертовски легко - и я мог бы подумать над многим из подхода C #.Я ожидаю, что это будет что-то простое - но я не знаком с тем, что я должен видеть в подходе CLI.(Я потратил несколько часов на поиски ответов и, наконец, чувствую, что мне нужно опубликовать вопрос, на который можно получить ответ).

Ответы [ 2 ]

4 голосов
/ 09 марта 2011
namespace myWrapper {

Оттуда пошло не так. Ваш .h файл объявляет класс в этом пространстве имен, его имя - myWrapper :: myWrappedService. Ваш файл .cpp объявляет еще один класс, который не находится в пространстве имен, его имя: myWrappedService. При разных именах компилятор не будет жаловаться на то, что один и тот же класс определен дважды. В первом классе нет реализации метода Connected, поэтому компоновщик пожаловался.

фрагменты sad_man's страдают тем же недостатком. Первый фрагмент определяет метод :: myWrappedService :: Connected (). Неверное пространство имен. Второй фрагмент имеет тот же недостаток, что и ваш.

Когда вы пишете библиотеку классов в управляемом коде, вам не нужен файл .h. Метаданные в сборке играют ту же роль, они содержат объявления типов в сборке. В вашем проекте нет другого файла .cpp, для которого требуется объявление класса, нет необходимости в .h. Так что просто напишите все в .cpp файле:

#include "stdafx.h"
// Note: header file removed

using namespace System;

namespace myWrapper {

    public ref class myWrappedService
    {
    public:
        myWrappedService() {}
        void Connect(String ^user, String ^password, String ^domain)
        {
            throw gcnew NotImplementedException;
        }
    };
}
2 голосов
/ 09 марта 2011

Ваш файл cpp не верен.Для использования заголовочных файлов cpp посмотрите здесь и здесь .C ++ / Cli имеет одинаковую концепцию заголовочных файлов и файлов cpp.На самом деле ваш файл cpp - это файл заголовка, который должен быть.

Также вы можете пойти так:

//myWrapper.h
#pragma once
#include "stdafx.h"
using namespace System;
namespace myWrapper {
  public ref class myWrappedService {
         myWrappedService();
         bool Connected(String ^user,String ^password,String ^domain);
  }
};

//myWrapper.cpp
//This is the main DLL file
#include "stdafx.h"
#include "myWrapper.h"
using namespace System;
namespace myWrapper
{
  myWrappedService::myWrappedService() {}
  bool myWrappedService::Connected(String ^user,String ^password,String ^domain)
  {
      bool result = false;
      return result;
  }
} 

Или вот так (один заголовок для вашего случая):

//myWrapper.h
//This is the main DLL file
#include "myWrapper.h"
using namespace System;
namespace myWrapper
{
public ref class myWrappedService
   {
      public:
            myWrappedService() {}
            bool Connected(String ^user,String ^password,String ^domain)
            {
               //just a simple result to start - no real functionality
               bool result = false;
               return result;
            }
   };
}
   // Remember? this was your cpp.

РЕДАКТИРОВАТЬ: я забыл о пространстве имен.Но я думаю, вы должны узнать, что такое заголовочные и cpp файлы.

...