仅一个函数的链接错误。相同 class 和 CPP 文件中具有相似签名的其他函数工作正常
Linkage error for one function only. Other functions with similar signature in same class and CPP file are working fine
以前有人问过类似的关于这种类型的链接错误的问题,我已经调查了其中的大部分(如果不是全部的话)。
这里有一些类似的问题,GitHub 和我调查过的 MSDN 来解决这个问题:
Whosebug 2
Whosebug 4
Whosebug 5
问题:
我有一个遗留产品,在 4 Visual Studio Solution
个文件中包含 400 多个 Visual Studio 项目。我面临的问题是一个 COM 组件项目,它应该使用从另一个项目创建的 dll
(包含静态函数); dll
中的所有静态函数都工作正常,除了一个,我正在尝试添加它。
创建 dll
的项目构建正常,没有任何错误,包含静态函数的 header
文件和 cpp
文件如下。
文件:InvocationInterface.h
using namespace some_namespace;
#ifdef _WIN64
#pragma pack(8)
#else
#pragma pack(1) // tag for search
#endif
typedef struct
{
long nDBMS;
long nDBMSVersion;
long nDBMSMinorVersion;
LPSTR szCaption;
LPSTR szRepGroupName;
std::vector<bool> xDBMSOptions;
EouGdmIdList selectedEntityIds;
BOOL bIsAlterScript;
int nInvoke;
LPSTR szConnectionInfo;
LPSTR szPassword;
LPSTR szOptionXML;
LPSTR szDDLPath;
} EouFEPARAM;
class EOU_EXPORT CUIInvocationInterface
{
public:
CUIInvocationInterface(void);
~CUIInvocationInterface(void);
// A lot of other similar static functions
static void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet,BOOL bShow);
static void setNSMCSV(GDMModelSetI* pxModelSet, CString csPath, bool append);
};
#pragma pack( pop, EouUIInvocationInterface_H_pack )
InvocationInterface.cpp
文件:
#include "Header_files"
//Constructor
CUIInvocationInterface::CUIInvocationInterface(void)
{
}
//Destructor
CUIInvocationInterface::~CUIInvocationInterface(void)
{
}
// Old legacy code working just fine if I remove the function that is casusing linking error
void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet, BOOL bShow)
{
return SetIncludeSysTables(pxModelSet, bShow);
}
// Function that is causing Linking Error
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
使用这些函数的 COM
组件正在以下列方式使用它们:
ComProxyFile.cpp
bool function(formal_parameters, ...)
{
...
...
CUIInvocationInterface::setNSMCSV(pxModelSet, strCSVpath, true);
CUIInvocationInterface::SetIncludeSysTablesForRevEng(pxModelSet, bIncludeSystemTables);
...
...
SOMECLASS::OnInvokeAFunction(args, ...);
return bRet;
}
函数 setNSMCSV
导致 LNK2019
错误,当我构建使用 dll
的 COM 组件时,声明了 20+
这样的静态函数并以类似的方式定义,但除了我正在尝试实现的 setNSMCSV
之外,其他一切都工作正常。
如果我构建使用这些函数的项目,则会出现以下错误:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: static void __cdecl CUIInvocationInterface::setNSMCSV(class GDMModelSetI *,class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > >,bool)"
如果我注释掉 CUIInvocationInterface::setNSMCSV(pxModelSet, strCSVpath, true);
行,那么它编译得很好。
我尝试给出 setNSMCSV
函数定义 __declspec(dllexport) __cdecl
、extern "C"
,并使用 pragma comment
,将 .lib
添加到 COM
组件使用函数,以及我能找到的其他类似问题中建议的其他内容。
为什么这个单一的函数会导致这个问题?其他函数具有相同的签名和类似的实现,但它们工作正常。
在 .cpp
文件中将 void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
更改为 void CUIInvocationInterface::setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
。您已将其声明为静态 class 函数,但定义为自由函数(而不是 class 成员)。
你的header:
class EOU_EXPORT CUIInvocationInterface
{
public:
CUIInvocationInterface(void);
~CUIInvocationInterface(void);
// A lot of other similar static functions
static void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet,BOOL bShow);
static void setNSMCSV(GDMModelSetI* pxModelSet, CString csPath, bool append); // <-- Static class member function
};
您的 cpp:
// Function that is causing Linking Error
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend) //<-- not a member function
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
在 InvocationInterface.cpp 中,您需要更改函数定义以包含 class 名称,即来自:
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
至:
void CUIInvocationInterface::setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
以前有人问过类似的关于这种类型的链接错误的问题,我已经调查了其中的大部分(如果不是全部的话)。 这里有一些类似的问题,GitHub 和我调查过的 MSDN 来解决这个问题:
Whosebug 2
Whosebug 4
Whosebug 5
问题:
我有一个遗留产品,在 4 Visual Studio Solution
个文件中包含 400 多个 Visual Studio 项目。我面临的问题是一个 COM 组件项目,它应该使用从另一个项目创建的 dll
(包含静态函数); dll
中的所有静态函数都工作正常,除了一个,我正在尝试添加它。
创建 dll
的项目构建正常,没有任何错误,包含静态函数的 header
文件和 cpp
文件如下。
文件:InvocationInterface.h
using namespace some_namespace;
#ifdef _WIN64
#pragma pack(8)
#else
#pragma pack(1) // tag for search
#endif
typedef struct
{
long nDBMS;
long nDBMSVersion;
long nDBMSMinorVersion;
LPSTR szCaption;
LPSTR szRepGroupName;
std::vector<bool> xDBMSOptions;
EouGdmIdList selectedEntityIds;
BOOL bIsAlterScript;
int nInvoke;
LPSTR szConnectionInfo;
LPSTR szPassword;
LPSTR szOptionXML;
LPSTR szDDLPath;
} EouFEPARAM;
class EOU_EXPORT CUIInvocationInterface
{
public:
CUIInvocationInterface(void);
~CUIInvocationInterface(void);
// A lot of other similar static functions
static void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet,BOOL bShow);
static void setNSMCSV(GDMModelSetI* pxModelSet, CString csPath, bool append);
};
#pragma pack( pop, EouUIInvocationInterface_H_pack )
InvocationInterface.cpp
文件:
#include "Header_files"
//Constructor
CUIInvocationInterface::CUIInvocationInterface(void)
{
}
//Destructor
CUIInvocationInterface::~CUIInvocationInterface(void)
{
}
// Old legacy code working just fine if I remove the function that is casusing linking error
void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet, BOOL bShow)
{
return SetIncludeSysTables(pxModelSet, bShow);
}
// Function that is causing Linking Error
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
使用这些函数的 COM
组件正在以下列方式使用它们:
ComProxyFile.cpp
bool function(formal_parameters, ...)
{
...
...
CUIInvocationInterface::setNSMCSV(pxModelSet, strCSVpath, true);
CUIInvocationInterface::SetIncludeSysTablesForRevEng(pxModelSet, bIncludeSystemTables);
...
...
SOMECLASS::OnInvokeAFunction(args, ...);
return bRet;
}
函数 setNSMCSV
导致 LNK2019
错误,当我构建使用 dll
的 COM 组件时,声明了 20+
这样的静态函数并以类似的方式定义,但除了我正在尝试实现的 setNSMCSV
之外,其他一切都工作正常。
如果我构建使用这些函数的项目,则会出现以下错误:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: static void __cdecl CUIInvocationInterface::setNSMCSV(class GDMModelSetI *,class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > >,bool)"
如果我注释掉 CUIInvocationInterface::setNSMCSV(pxModelSet, strCSVpath, true);
行,那么它编译得很好。
我尝试给出 setNSMCSV
函数定义 __declspec(dllexport) __cdecl
、extern "C"
,并使用 pragma comment
,将 .lib
添加到 COM
组件使用函数,以及我能找到的其他类似问题中建议的其他内容。
为什么这个单一的函数会导致这个问题?其他函数具有相同的签名和类似的实现,但它们工作正常。
在 .cpp
文件中将 void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
更改为 void CUIInvocationInterface::setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
。您已将其声明为静态 class 函数,但定义为自由函数(而不是 class 成员)。
你的header:
class EOU_EXPORT CUIInvocationInterface
{
public:
CUIInvocationInterface(void);
~CUIInvocationInterface(void);
// A lot of other similar static functions
static void SetIncludeSysTablesForRevEng(GDMModelSetI* pxModelSet,BOOL bShow);
static void setNSMCSV(GDMModelSetI* pxModelSet, CString csPath, bool append); // <-- Static class member function
};
您的 cpp:
// Function that is causing Linking Error
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend) //<-- not a member function
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
在 InvocationInterface.cpp 中,您需要更改函数定义以包含 class 名称,即来自:
void setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}
至:
void CUIInvocationInterface::setNSMCSV(GDMModelSetI* pModelSet, CString & sFilePath, bool bAppend)
{
CWnd * wnd = nullptr;
EouRESetOptions ForRE(wnd);
ForRE.ProcessCSV(sFilePath, true);
}