I have to create a static-linking standalone .exe file from my .cpp and .h files.
The only obstacle I need to overcome is being able to call the same function m_pListAll()
from two .cpp files, main.cpp
and window.cpp
(defining a class called Window
).
The only problem is (for unknown reasons) I cannot #include
the header file that defines m_peDO() twice across main.cpp
and window.cpp
, I can only do it once because the header file sets up something called "dynamic linking" with some bizarre thing called HINSTANCE
(wrong: actual reason is in answer section):
//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
There are more functions, but lets just pretend I want to use tListAll m_pListAll in main.cpp and window.cpp. My Qt project contains the following files:
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().
Why am I using this wierd HINSTANCE thing? Something to do with my .lib file being incompatible with minGW. If I add the library to statically be part of compilation, i get: :-1: error: No rule to make target 'C:/Users/Joey/Documents/ValvePermissions/libLabJackU.a', needed by 'release\ValvePermissions.exe'. Stop.
What should I do? I just want that function to be in the scope of window.cpp, but I don't want to use that header twice because of the errors.
Your problem is that you've defined hDLLInstance
and m_pListAll
in the header, rather than simply declare them; thus every translation unit which includes this header will create a public implementation of each of these variables, all of which collide at link time.
You need to add the extern
keyword to each of these definitions in the header, thus converting them to declarations, and copy your original definitions, (i.e. without the extern
keyword), into just one of your translation units, (main.cpp
perhaps), so that there is exactly one implementation defined at link time. Thus, in your header, you have:
//Declare a variable to hold a handle to the loaded DLL.
extern HINSTANCE hDLLInstance;
//Declare variables for the UD functions.
extern tListAll m_pListAll;
and in main.cpp
, (for example):
//Define a variable to hold a handle to the loaded DLL.
HINSTANCE hDLLInstance;
//Define variables for the UD functions.
tListAll m_pListAll;