0

I'm having difficulties linking C++ CLI projects.

In one of my CLR projects I have a native baseclass (containing managed methods and members) which I'm trying to inherit to a subclass in another project. The compiler gives the following errors:

error LNK2028: unresolved token (0A0000CE) "protected: bool __thiscall CWpfTemplateDlg::SetIsCloseButtonEnabled(bool)" (?SetIsCloseButtonEnabled@CWpfTemplateDlg@@$$FIAE_N_N@Z) referenced in function "protected: virtual class System::Windows::Controls::UserControl ^ __clrcall CTestWpf::InitWpfContent(void)" (?InitWpfContent@CTestWpf@@$$FMAMP$AAVUserControl@Controls@Windows@System@@XZ)  B:\Trunk\Edison\ForetagsplatsenCLR\ForetagsplatsenCLR.obj   ForetagsplatsenCLR

error LNK2019: unresolved external symbol "protected: bool __thiscall CWpfTemplateDlg::SetIsCloseButtonEnabled(bool)" (?SetIsCloseButtonEnabled@CWpfTemplateDlg@@$$FIAE_N_N@Z) referenced in function "protected: virtual class System::Windows::Controls::UserControl ^ __clrcall CTestWpf::InitWpfContent(void)" (?InitWpfContent@CTestWpf@@$$FMAMP$AAVUserControl@Controls@Windows@System@@XZ)   B:\Trunk\Edison\ForetagsplatsenCLR\ForetagsplatsenCLR.obj   ForetagsplatsenCLR

The Project containing the baseclass compiles without problem, generating .lib, .dll, .exp and .pdb file. I have linked the project by creating a reference in "Common Properties", setting include directory and explicitly declaring the .lib file in "Configuration Properties->Linker->Input".

Here is the code:

// Header
class CWpfTemplateDlg abstract : public CDialog
{
public:
   CWpfTemplateDlg::CWpfTemplateDlg( CWnd* pParent ) :
      CDialog( IDD_WPF_TEMPLATE_DIALOG, NULL )
   {
   }
   virtual CWpfTemplateDlg::~CWpfTemplateDlg()
   {
   }    

protected:
   virtual std::string GetCaption() = 0;
   virtual System::Windows::Controls::UserControl^ InitWpfContent() = 0;
   bool SetIsCloseButtonEnabled( bool enabled );

private:
   DECLARE_MESSAGE_MAP()
   BOOL OnInitDialog();
   afx_msg BOOL OnHelpInfo( HELPINFO* pHelpInfo );

protected:
   HWND m_wpfChild;
   gcroot<System::Windows::Interop::HwndSource^> m_hwndSource;
   gcroot<System::Windows::Controls::UserControl^> m_wpfControl;
};



// Cpp
bool CWpfTemplateDlg::SetIsCloseButtonEnabled( bool enabled )
{
    ...
}

BOOL CWpfTemplateDlg::OnInitDialog()
{
    ...
}

BOOL CWpfTemplateDlg::OnHelpInfo( HELPINFO* pHelpInfo )
{
    return TRUE;
}

BEGIN_MESSAGE_MAP(CWpfTemplateDlg, CDialog)
    ON_WM_HELPINFO()
END_MESSAGE_MAP()

And the subclass:

class CTestWpf : public CWpfTemplateDlg
{
public:
    CTestWpf( CWnd* pParent = NULL ) :
        CWpfTemplateDlg( pParent )
    {
    }

protected:
    System::Windows::Controls::UserControl^ InitWpfContent()
    {
        SetIsCloseButtonEnabled(false);
        System::Windows::Controls::UserControl^ wpfControl = nullptr;

        return wpfControl;
    }

    std::string GetCaption()
    {
        return "Caption";
    }
};

Is there anyone out there who knows whats going on?


@Kratz

Yes, I did add the library path.

/VERBOSE does not present any errors related to loading the lib file.

Dependency Walker gives me the following errors:

Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.

Error: Modules with different CPU types were found.

Warning: At least one delay-load dependency module was not found.

Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

The first error tells me that there are unresolved tokens/externals (which we already know from the errors in the compiler).

All my projects use the same platform type so I'm not sure why I get the second error. Any ideas?

"Delay-load dependency modules" are not my strongest area so I'm pretty much at a loss here. I get the general concept of them, but I don't understand the implication in this scenario. Can anyone explain whats going on and how I can go about fixing the problem?

Community
  • 1
  • 1
  • This looks fairly unhealthy, *abstract* is a C++/CLI keyword but you are using it in a native C++ class. Sounds like you are mixing stuff up badly, the linker tends to remind you about that. – Hans Passant Jun 20 '13 at 12:28
  • there is a abstract-keyword in native c++ aswell. Do you mean that CLI isn't compatible with all keywords in native? Is there some way I should flag the keyword as being explicitly native? Edit: Also, removing the abstract doesn't help (still the same errors). It's only there to make the code easier to read. Since the class has methods that are pure virtual, the class is implicitly abstract. – Fredrik Kuylenstierna Jun 20 '13 at 12:48
  • or rather, there is a abstract keyword in native VC++, to be precise. http://msdn.microsoft.com/en-us/library/vstudio/b0z6b513.aspx – Fredrik Kuylenstierna Jun 20 '13 at 13:02
  • You wrote you set the correct include path and adden the lib file generated by your base project. Did you also add the path to the library under linker? Did you try to set the linker output to verbose and check if the lib is found? Did you check the created .dll with dependency walker if it exports the correct symbol? – Kratz Jun 20 '13 at 16:39

0 Answers0