开发者

Visual C++/CLI - CLR Class - LNK2020 Error - how to fix?

I have a project, where I must connect to a library that is C based, and I was not able to get at the functions from C# using the DLLImport. I have to use a project that is C++/CLI based to surface these functions for use. (more to that story but not important).

I studied C++ over 10 years ago, so forgive me if this seems like it is naive.

I purchased a few books on the C++/CLI implementation last year, and have some grasp of what is involved - I only dug into those books for this project. (I have been a programmer for a long time).

I thought I had better start a small project example project to familiarize myself with what will be involved, to make sure I could compile, etc. I started a project using Visual Studio 2008 SP1; Visual C++ > CLR > Class Library. In the project - I want to use both managed and native from the DLL. So the /clr switch is used.

I have used other names in the real code; but this is very, very close. (there are no other files, or functions at this point)

Header:

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

And the implementation has this.

//myWrapper.cpp
//This is the main DLL file
#include "stdafx.h"
#include "myWrapper.h"
using name开发者_高级运维space 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;
            }
   };

That is the code - that compiles but gets linker errors.

error LNK2020: unresolved token (06000002) myWrapper.myWrappedService::Connected

fatal error LNK1120: 1 unresolved external.

This looked dead easy - and I might be thinking to much from a C# approach. I expect this to be something simple - but I am not familiar with what I should be seeing in the CLI approach. (I spent a few hours looking for answers and finally feel I need to post a question where it might get answered).


namespace myWrapper {

It went wrong from there. Your .h file declares a class inside that namespace, its name is myWrapper::myWrappedService. Your .cpp file declares another class that is not in a namespace, its name is ::myWrappedService. Different names, the compiler won't complain about seeing the same class defined twice. The first class doesn't have an implementation of the Connected method, that's why the linker complained.

sad_man's snippets suffer the same flaw. The first snippet defines the ::myWrappedService::Connected() method. Wrong namespace. The second snippet has the same flaw as yours.

When you write a class library in managed code then you don't need a .h file. Metadata in an assembly plays the same role, it contains the declarations of the types in the assembly. There is no other .cpp file in your project that needs the declaration of the class, no need for the .h. So just write everything in .cpp file:

#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;
        }
    };
}


Your cpp file is all wrong. For usage of cpp an header files look at here and here. C++/Cli has the same concept of header and cpp files. Actually your cpp file is what a header file is supposed to be.

Also you can go like this :

//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;
  }
} 

Or like this (One header for your case):

//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.

EDIT : I have forgotten about the namespace. But I think you should learn what header and cpp files are.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜