locked
VStudio 2013 dllimport causes lnk2019 error RRS feed

  • Question

  • Using VStudio 2013 I'm linking to an MFC shared DLL where a function is exported in a def file as follows

    ; IDBReg.def : Declares the module parameters for the DLL.

    LIBRARY      "IDBReg"
    DESCRIPTION  'IDBReg Windows Dynamic Link Library'

    EXPORTS
        ; Explicit exports can go here
    TestXXX

    Underlying function is

    CString TestXXX()
    {
    return("ben there");
    }

    I import using __declspec(dllimport) CString TestXXX() if my consuming DLL and have included a path to the functions lib file in project\config\vcc++ directories as 

    .....IDBReg\Debug

    and also in the linker\general\additional library directories as 

    ....IDBReg\Debug

    but still getting the error.

    Error 1 error LNK2019: unresolved external symbol "__declspec(dllimport) class ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __cdecl TestXXX(void)" (__imp_?TestXXX@@YA?AV?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@XZ) referenced in function _HttpExtensionProc@4 c:\Users\Dale\Documents\Visual Studio 2013\Projects\IIS8_Interform\IIS8_Interform\Iform.obj IIS8_Interform

    I've just tried including the header file of the exporting dll in to the consuming dll which leads to the error

    Error 1 error C1189: #error :  WINDOWS.H already included.  MFC apps must not #include <windows.h> c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\afxv_w32.h 16 1 IIS8_Interform

    Is there something else I should be doing ?



    Dale


    Tuesday, March 11, 2014 2:03 PM

Answers

  • On 3/11/2014 10:03 AM, DJRRRRR wrote:

    Using VStudio 2013 I'm linking to an MFC shared DLL where a function is exported in a def file as follows

    ; IDBReg.def : Declares the module parameters for the DLL.

    LIBRARY      "IDBReg"
    DESCRIPTION  'IDBReg Windows Dynamic Link Library'

    EXPORTS
         ; Explicit exports can go here
    TestXXX

    Underlying function is

    CString TestXXX()
    {
    return("ben there");
    }

    Mark the function extern "C" (unconditionally; you would need this both in the EXE and the DLL). You don't need __declspec(dllimport).

    Having said that, note that it's unwise to export a function from a DLL that uses an MFC class in its signature. This would only work if both EXE and DLL are built with the same version of the same compiler, with the same settings (e.g. both Debut or both Release). Otherwise, they won't agree on precisely what "CString" means.


    Igor Tandetnik
    Wednesday, March 12, 2014 2:30 PM
  • Igor,

    You're a star, I've been working on this for days and didn't see the obvious.

    Yes ISAPI dll is using the atl version of cstring whereas the mfc dll was using the mfc version. I included altstr.h in the mfc dll and altered my function to return a CAtlString type as below. 

    extern "C" __declspec(dllexport) CAtlString CMyString::MyMethod2()
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    CAtlString x = _T("hello from your libary dll");
    //CString x = _T("hello");
    return(x);

    }

    Now works fine, thanks to David  and May.


    Dale

    • Marked as answer by DJRRRRR Thursday, March 13, 2014 5:15 PM
    Thursday, March 13, 2014 5:15 PM

All replies

  • Hi Dale,

    I am moving your thread into the Visual C++ Forum for dedicated support. Thanks for your understanding.

    Best Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, March 12, 2014 5:41 AM
  • Hi Dale,

    According to your description, you receive an LNK2019 error message when you build a Visual C++  application that
    uses a CString-derived class from a DLL file.

    There is a known issue related with this in VS2005, I am not sure if the VS2013 exists similar issue, you can refer to the solution for VS2005 to check if it can fix the issue you meet in VS2013.

    http://support.microsoft.com/kb/309801

    In order to make others know this work around, I display it below:

    To resolve this issue, explicitly import the template class   for CStringT and CSimpleStringT in the precompiled header (stdafx.h) file, as follows:

    template class __declspec(dllimport) CStringT<TCHAR, StrTraitMFC<TCHAR, ChTraitsCRT<TCHAR> > >;

    template class __declspec(dllimport) CSimpleStringT<TCHAR>;

    Hope this can help you.

    Any issue, please feel free to let me know.

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, March 12, 2014 7:57 AM
  • On 3/11/2014 10:03 AM, DJRRRRR wrote:

    Using VStudio 2013 I'm linking to an MFC shared DLL where a function is exported in a def file as follows

    ; IDBReg.def : Declares the module parameters for the DLL.

    LIBRARY      "IDBReg"
    DESCRIPTION  'IDBReg Windows Dynamic Link Library'

    EXPORTS
         ; Explicit exports can go here
    TestXXX

    Underlying function is

    CString TestXXX()
    {
    return("ben there");
    }

    Mark the function extern "C" (unconditionally; you would need this both in the EXE and the DLL). You don't need __declspec(dllimport).

    Having said that, note that it's unwise to export a function from a DLL that uses an MFC class in its signature. This would only work if both EXE and DLL are built with the same version of the same compiler, with the same settings (e.g. both Debut or both Release). Otherwise, they won't agree on precisely what "CString" means.


    Igor Tandetnik
    Wednesday, March 12, 2014 2:30 PM
  • Thanks for the replies. Following http://support.microsoft.com/kb/309801 I managed created a Win32 console app with MFC supprt to call a regular MFC dll function <MyMethod2>.

    Is it possible to call <MyMethod2> from a dll using only standard windows libraries, the calling dll is an isapi program , at the moment I'm getting an error 

    Error 2 error C2146: syntax error : missing ';' before identifier 'MyMethod2' , class definition below

    class IMPEXP CMyString : public CString
    {
    public:
    CMyString();
    virtual ~CMyString();

    void MyMethod();
    CString MyMethod2();
    };

    Clearly the CString type is not recognised.

    I tried putting 

    template class __declspec(dllimport) CStringT<TCHAR, StrTraitMFC<TCHAR, ChTraitsCRT<TCHAR> > >;
    template class __declspec(dllimport) CSimpleStringT<TCHAR>;

    but get numerous errors first of which is

    9 IntelliSense: CSimpleStringT is not a template

    The reason for my question is that I'm trying to port an old ISAPI app to VStudio 2013 , the MFC ISAPI classes I previously used no longer exist. I can rewrite the ISAPI routines using windows libraries but there are numerous MFC libary DLLs being called.

    Thanks for any advice.



    Dale

    Wednesday, March 12, 2014 6:29 PM
  • Hi Dale

    Thanks for your feedback.

    Based on your information, have you considered the suggestion from Igor? I think you can have a try to use extern "C" instead of __declspec(dllimport).

    By the way, here is an article related with CString, ATL and MFC, you may have reference to it.

    Linker Errors, CString, ATL, MFC, and YOU!

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, March 13, 2014 6:43 AM
  • On 3/12/2014 2:29 PM, DJRRRRR wrote:

    Is it possible to call <MyMethod2> from a dll using only standard windows libraries, the calling dll is an isapi program , at the moment I'm getting an error

    Clearly the CString type is not recognised.

    Of course - CString is defined by MFC, and the caller isn't built with MFC support.

    Like I said, both modules would have to be build with the same compiler and the same settings; this includes "Use MFC" setting.

    The reason for my question is that I'm trying to port an old ISAPI app to VStudio 2013 , the MFC ISAPI classes I previously used no longer exist. I can rewrite the ISAPI routines using windows libraries but there are numerous MFC libary DLLs being called.

    Can't you rewrite the ISAPI routines using windows libraries, and enable MFC while doing so? You don't have to actually use anything beyond CString if you don't want to.


    David Wilkinson | Visual C++ MVP
    Thursday, March 13, 2014 12:55 PM
  • David,

    I've revisited the functions in my MFC dll which now look as follows...


    extern

    "C"__declspec(dllexport) voidCMyString::MyMethod(void)

    {

    AFX_MANAGE_STATE(AfxGetStaticModuleState())

    CStringx = _T("hello");

    AfxMessageBox(

    _T("foo is called"));

    }


    extern

    "C"__declspec(dllexport) CStringCMyString::MyMethod2()

    {

    AFX_MANAGE_STATE(AfxGetStaticModuleState())

    CStringx = _T("hello");

    return(_T("hello"));

    }

    Work fine when linking to from a win32 console DLL with MFC support but from my ISAPI dll I get the following error

    Error 1 error LNK2019: unresolved external symbol "public: class ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __thiscall CMyString::MyMethod2(void)" (?MyMethod2@CMyString@@QAE?AV?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@XZ) referenced in function _HttpExtensionProc@4 C......Iform.obj

    In the ISAPI code I'm linking using...

    #include ".....MyString.h" which contains the functions and using

    #pragma "..\\Debug\\MyLib" to link the library

    The ISAPI project has MFC support.

    I've looked at the guidance at http://msdn.microsoft.com/en-us/library/vstudio/30c674tx(v=vs.100).aspx and seem to be doing everything recommended.


    Dale

    Thursday, March 13, 2014 3:02 PM
  • Thought it worth adding that the ISAPI project is set was initially set up as a blank Wind32 console app which does not give the option for MFC support. The project therefore uses standard windows libraries (WINAPI function)  using the headers 'windows.h', 'hpptext', <string>, atlstr.h, <sstream>.


    Dale

    Thursday, March 13, 2014 3:16 PM
  • Error 1 error LNK2019: unresolved external symbol "public: class ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __thiscall CMyString::MyMethod2(void)" (?MyMethod2@CMyString@@QAE?AV?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@XZ) referenced in function _HttpExtensionProc@4 C......Iform.obj

    The caller is attempting to use the ATL version of CString, not the MFC version.

    CString is actually a typedef for a complicated template class CStringT - exactly which instatiation of the template it's a typedef for depends on several project settings. Which is why using CString across project boundaries can only work when both projects are built with the exact same settings. Yours are still different, in some way.


    Igor Tandetnik

    Thursday, March 13, 2014 4:00 PM
  • Igor,

    You're a star, I've been working on this for days and didn't see the obvious.

    Yes ISAPI dll is using the atl version of cstring whereas the mfc dll was using the mfc version. I included altstr.h in the mfc dll and altered my function to return a CAtlString type as below. 

    extern "C" __declspec(dllexport) CAtlString CMyString::MyMethod2()
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    CAtlString x = _T("hello from your libary dll");
    //CString x = _T("hello");
    return(x);

    }

    Now works fine, thanks to David  and May.


    Dale

    • Marked as answer by DJRRRRR Thursday, March 13, 2014 5:15 PM
    Thursday, March 13, 2014 5:15 PM