0
error LNK2001: unresolved external symbol "public: virtual void __cdecl pcl::visualization::PCLVisualizer::FPSCallback::Execute(class vtkObject *,unsigned long,void *)" (?Execute@FPSCallback@PCLVisualizer@visualization@pcl@@UEAAXPEAVvtkObject@@KPEAX@Z)
1>C:\Users\hatea\Documents\Visual Studio 2015\Projects\PCLTester\x64\Debug\PCLTester.dll : fatal error LNK1120: 1 unresolved externals

I have thoroughly exhausted all avenues dealing with this issue. I checked here, and I found a similar question/answer series: error LNK2001 when including "pcl_visualizer.h"

The problem is that I do not want to comment out the FPSCallback method. I need it for the VTK visualizer I am using. I have determined that I only receive the unresolved external error when I reference the .h file in a managed C++/CLI library.

#pragma once
#pragma unmanaged
#include <pcl/visualization/pcl_visualizer.h>
#pragma managed

using namespace System;

namespace PCLTesterCLI 
{
    public ref class PCLTesterCLI
    {
    public:
        PCLTesterCLI();
        virtual ~PCLTesterCLI();
    };
}

If I do the same in an unmanaged Win32 library, the library is successfully built.

#pragma once
#include <pcl/visualization/pcl_visualizer.h>

class PCLTester
{
public:
    PCLTester();
    virtual ~PCLTester();
};

Here is the segment from pcl_visualizer.h:

    struct FPSCallback : public vtkCommand
    {
      static FPSCallback *New () { return (new FPSCallback); }

      FPSCallback () : actor (), pcl_visualizer (), decimated () {}
      FPSCallback (const FPSCallback& src) : vtkCommand (), actor (src.actor), pcl_visualizer (src.pcl_visualizer), decimated (src.decimated) {}
      FPSCallback& operator = (const FPSCallback& src) { actor = src.actor; pcl_visualizer = src.pcl_visualizer; decimated = src.decimated; return (*this); }

      virtual void 
      Execute (vtkObject*, unsigned long event_id, void*);

      vtkTextActor *actor;
      PCLVisualizer* pcl_visualizer;
      bool decimated;
    };

    /** \brief The FPSCallback object for the current visualizer. */
    vtkSmartPointer<FPSCallback> update_fps_;

Here is the segment from pcl_visualizer.cpp:

void
pcl::visualization::PCLVisualizer::FPSCallback::Execute (
    vtkObject* caller, unsigned long, void*)
{
    vtkRenderer *ren = reinterpret_cast<vtkRenderer *> (caller);
    float fps = 1.0f / static_cast<float> (ren->GetLastRenderTimeInSeconds ());
    char buf[128];
    sprintf (buf, "%.1f FPS", fps);
    actor->SetInput (buf);
}

Any ideas why the structure and member function conflict in a managed environment?

The reason that my question is unique is that my symbols error was not a result of anything I did: e.g. declaring a function without defining it, having a syntax error that results in the function not being properly defined, or leaving out a .lib dependency from Linker->Input. In my case, I have all the correct .lib files linked and the function from pcl::visualization seems well defined. For some strange reason, it is still being missed at compile time in the managed library. I copied my dependencies from my managed .vcxproj to my unmanaged .vcxproj to verify that it was not a dependency issue. Both classes are setup with the minimum class requirements to prevent conflicts in that regard. Both projects have the same .h file and .lib files linked.

Community
  • 1
  • 1
Wurth
  • 11
  • 3
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Dec 17 '16 at 00:59
  • I am unsure to which answer you refer this is a duplicate. I see nothing so far reading through the answers in the link you posted about managed/unmanaged linkage errors. Why would a .lib definition work in unmanaged but not managed static/class libraries? I am also curious why I was able to re-define the function in my managed c++ file without meeting any compile errors (I expected some conflict that was preventing the .lib definition from working). – Wurth Dec 17 '16 at 01:48
  • There are dozens of answers to that post, which describe many causes for unresolved externals or references. If you've not found one that deals with your issue, you've not read enough of them. A search here for LNK1120 turns up nearly 3000 results, which it is highly unlikely you have read before writing this question. – Ken White Dec 17 '16 at 01:50
  • Most LNK1120 errors are resolved by providing the correct syntax because it is user code that caused the issue. In my case, it is an external library. I have yet to find a similar case to mine after looking through dozens (yes, I admit to not reading 3000+ results) of LNK1120 errors. If you can find a case where the correct dependencies are provided and that still results in a LNK1120 for managed code but not for unmanaged, then I'll agree that I did not do enough research. – Wurth Dec 17 '16 at 02:02
  • So your expectation is *I don't feel like doing all of the research myself, but if you'll do it for me and find me a link I'll agree I didn't try hard enough.*? Not going to happen. Do your own research. It's ludicrous to expect everyone to be able to get a tailored answer to their individual problem that generates unresolved external/reference error; there are literally billions of symbols that can be affected by this issue, and having a billion very similar answers tailored to those very similar problems is simply a waste. Do your own research to find the existing answer that resolves yours. – Ken White Dec 17 '16 at 02:09
  • And your claim that you have *thoroughly exhausted all avenues* is patently false, as your previous comment indicates you've done no such thing. We're not your personal research assistants. – Ken White Dec 17 '16 at 02:11
  • All I was asking for was clarification as to why a library definition fails in managed code. I even provided the function's definition and declaration to see if someone out there knows what about the two causes a conflict with a CLI class library. And yes, I have done extensive research on the matter for the past few hours. I tried multiple things on my own for 2-3 hours before that. I am putting in the work, but I signed up for this site in hopes others would be willing to share their experience and help me learn more. I thought that's what these communities were about. – Wurth Dec 17 '16 at 02:20

1 Answers1

0

Interestingly, I solved this issue by placing the pcl_visualizer code into my managed c++ code at the top. I had to add a header as well:

#include <vtkTextActor.h>

void
pcl::visualization::PCLVisualizer::FPSCallback::Execute(vtkObject* caller, unsigned long, void*)
{
    vtkRenderer *ren = reinterpret_cast<vtkRenderer *> (caller);
    float fps = 1.0f / static_cast<float> (ren->GetLastRenderTimeInSeconds());
    char buf[128];
    sprintf(buf, "%.1f FPS", fps);
    actor->SetInput(buf);
}

The other option is to go into pcl_visualizer.h and comment out the offending line (I do not know why this line causes issues, but I narrowed it down to this, and my vtk visualizer still works!):

  //FPSCallback (const FPSCallback& src) : vtkCommand (), actor (src.actor), pcl_visualizer (src.pcl_visualizer), decimated (src.decimated) {}

The code then looks like:

struct FPSCallback : public vtkCommand
{
  static FPSCallback *New () { return (new FPSCallback); }

  FPSCallback () : actor (), pcl_visualizer (), decimated () {}
  //FPSCallback (const FPSCallback& src) : vtkCommand (), actor (src.actor), pcl_visualizer (src.pcl_visualizer), decimated (src.decimated) {}
  FPSCallback& operator = (const FPSCallback& src) { actor = src.actor; pcl_visualizer = src.pcl_visualizer; decimated = src.decimated; return (*this); }

  virtual void 
  Execute (vtkObject*, unsigned long event_id, void*);

  vtkTextActor *actor;
  PCLVisualizer* pcl_visualizer;
  bool decimated;
};

/** \brief The FPSCallback object for the current visualizer. */
vtkSmartPointer<FPSCallback> update_fps_;
Wurth
  • 11
  • 3