奇怪的是header不能同时包含在main.cpp和window.cpp中(一个class)
Weird header can't be included in both main.cpp and window.cpp (a class)
我必须从我的 .cpp 和 .h 文件创建一个 static-linking 独立的 .exe 文件。
我需要克服的唯一障碍是能够从两个 .cpp 文件 main.cpp
和 window.cpp
调用相同的函数 m_pListAll()
(定义 class称为 Window
).
唯一的问题是(出于未知原因)我无法 #include
定义 m_peDO() 两次的 header 文件跨越 main.cpp
和 window.cpp
,我只能做一次,因为 header 文件设置了一些叫做 "dynamic linking" 的东西和一些叫做 HINSTANCE
的奇怪东西(错误:实际原因在答案部分):
//linking.h
// This is an extra header file for dynamic linking of the LabJackUD driver.
// support@labjack.com
#ifdef __cplusplus
extern "C"
{
#endif
//For dynamic linking, we first define structures that have the same format
//as the desired function prototype.
typedef LJ_ERROR (CALLBACK *tListAll) (long, long, long *, long *, long *, double *);
//Define a variable to hold a handle to the loaded DLL.
HINSTANCE hDLLInstance;
//Define variables for the UD functions.
tListAll m_pListAll;
#ifdef __cplusplus
} // extern C
#endif
还有更多的功能,但让我们假装我想在main.cpp和window.cpp中使用tListAll m_pListAll。我的 Qt 项目包含以下文件:
main.cpp //main code
window.h //header defining a class used in main
window.cpp //cpp thing defining that class's methods
peripheral.h //header file to control my peripheral device
peripheral.lib //library file to control my peripheral device (VC6 only not minGW?!)
linking.h //thing that solves(?) the minGW/VC6 library incompatibility (read on)
Scenario 1) #include <linking.h> in **only** main.cpp
Outcome: m_pListAll() only in scope of main.cpp, out of scope for window.cpp
Scenario 2) #include <linking.h> in **both** main.cpp AND window.cpp
Outcome: Redefinition errors for redefining hDLLInstance and m_pListAll().
为什么我要使用这个奇怪的 HINSTANCE 东西?我的 .lib 文件与 minGW 不兼容有关。如果我将库添加为静态编译的一部分,我得到:
:-1: 错误:'release\ValvePermissions.exe' 需要创建目标 'C:/Users/Joey/Documents/ValvePermissions/libLabJackU.a' 的规则。停止。
我该怎么办?我只希望该函数在 window.cpp 的范围内,但由于错误,我不想使用 header 两次。
您的问题是您在 header 中 定义了 hDLLInstance
和 m_pListAll
,而不是简单地 声明 他们;因此 每个 包含此 header 的翻译单元将创建每个这些变量的 public 实现 ,所有这些在 link 时间发生碰撞。
您需要将 extern
关键字添加到 header 中的每个定义中,从而将它们转换为 声明 、并且复制您的原始定义(即没有extern
关键字)到一个您的翻译单元,(可能是 main.cpp
),因此在 link 时恰好有一个实现 defined。因此,在您的 header 中,您有:
//Declare a variable to hold a handle to the loaded DLL.
extern HINSTANCE hDLLInstance;
//Declare variables for the UD functions.
extern tListAll m_pListAll;
并且在main.cpp
中,(例如):
//Define a variable to hold a handle to the loaded DLL.
HINSTANCE hDLLInstance;
//Define variables for the UD functions.
tListAll m_pListAll;
我必须从我的 .cpp 和 .h 文件创建一个 static-linking 独立的 .exe 文件。
我需要克服的唯一障碍是能够从两个 .cpp 文件 main.cpp
和 window.cpp
调用相同的函数 m_pListAll()
(定义 class称为 Window
).
唯一的问题是(出于未知原因)我无法 #include
定义 m_peDO() 两次的 header 文件跨越 main.cpp
和 window.cpp
,我只能做一次,因为 header 文件设置了一些叫做 "dynamic linking" 的东西和一些叫做 HINSTANCE
的奇怪东西(错误:实际原因在答案部分):
//linking.h
// This is an extra header file for dynamic linking of the LabJackUD driver.
// support@labjack.com
#ifdef __cplusplus
extern "C"
{
#endif
//For dynamic linking, we first define structures that have the same format
//as the desired function prototype.
typedef LJ_ERROR (CALLBACK *tListAll) (long, long, long *, long *, long *, double *);
//Define a variable to hold a handle to the loaded DLL.
HINSTANCE hDLLInstance;
//Define variables for the UD functions.
tListAll m_pListAll;
#ifdef __cplusplus
} // extern C
#endif
还有更多的功能,但让我们假装我想在main.cpp和window.cpp中使用tListAll m_pListAll。我的 Qt 项目包含以下文件:
main.cpp //main code
window.h //header defining a class used in main
window.cpp //cpp thing defining that class's methods
peripheral.h //header file to control my peripheral device
peripheral.lib //library file to control my peripheral device (VC6 only not minGW?!)
linking.h //thing that solves(?) the minGW/VC6 library incompatibility (read on)
Scenario 1) #include <linking.h> in **only** main.cpp
Outcome: m_pListAll() only in scope of main.cpp, out of scope for window.cpp
Scenario 2) #include <linking.h> in **both** main.cpp AND window.cpp
Outcome: Redefinition errors for redefining hDLLInstance and m_pListAll().
为什么我要使用这个奇怪的 HINSTANCE 东西?我的 .lib 文件与 minGW 不兼容有关。如果我将库添加为静态编译的一部分,我得到: :-1: 错误:'release\ValvePermissions.exe' 需要创建目标 'C:/Users/Joey/Documents/ValvePermissions/libLabJackU.a' 的规则。停止。
我该怎么办?我只希望该函数在 window.cpp 的范围内,但由于错误,我不想使用 header 两次。
您的问题是您在 header 中 定义了 hDLLInstance
和 m_pListAll
,而不是简单地 声明 他们;因此 每个 包含此 header 的翻译单元将创建每个这些变量的 public 实现 ,所有这些在 link 时间发生碰撞。
您需要将 extern
关键字添加到 header 中的每个定义中,从而将它们转换为 声明 、并且复制您的原始定义(即没有extern
关键字)到一个您的翻译单元,(可能是 main.cpp
),因此在 link 时恰好有一个实现 defined。因此,在您的 header 中,您有:
//Declare a variable to hold a handle to the loaded DLL.
extern HINSTANCE hDLLInstance;
//Declare variables for the UD functions.
extern tListAll m_pListAll;
并且在main.cpp
中,(例如):
//Define a variable to hold a handle to the loaded DLL.
HINSTANCE hDLLInstance;
//Define variables for the UD functions.
tListAll m_pListAll;