I am translating six Visual Basic projects into C and C++ in CodeLite. In CodeLite, I made one workspace with six projects in it. I set up five of the projects to compile to a dll, and the last one to an executable. The last project is the main program, and is a C++ GUI using wxCrafter.
My problem is that I can build a dll from the first project, but I can't get any of the other projects to reference the first dll during the linking process. The linking of the other projects all error out.
To make it easier to describe this problem, I'll call my projects:
Project_A (contains global procedures and identifiers)
Project_B
Project_C
Project_D
Project_E
Project_Z (main program)
Project_A contains global procedures and identifiers. It is compiling into a dll very nicely, and the dll is getting put in the directory that I specified.
The next thing I want to do is compile Project_B. Project_B calls global utilities in Project_A.
I found that if I add the source code for the global procedures and identifiers to Project_B, then Project_B.dll builds just fine. But it seems wasteful to have the same code repeated in every project. It would be better to just have that code in Project A, and the other projects reference it.
I tried building Project_B WITH the *.h files from Project_A, but WITHOUT the *.c files from Project_A, and adding the path to the directory where the dlls reside, as needed. In the Project_B Settings/Global Settings/Libraries, I also added Project_A as a library. But when I link Project B, I get "undefined reference to 'x'" errors for the identifiers in Project_A.
What do I need to do to make Project_B know it can find the utilities and global identifiers in Project_A.dll?
Thank you!
Colleen
How to Make Project DLLs Reference each other in a Workspace
- ColleenKobe
- CodeLite Expert
- Posts: 130
- Joined: Wed Mar 30, 2016 4:31 pm
- Genuine User: Yes
- IDE Question: C++
- Contact:
- eranif
- CodeLite Plugin
- Posts: 6375
- Joined: Wed Feb 06, 2008 9:29 pm
- Genuine User: Yes
- IDE Question: C++
- Contact:
Re: How to Make Project DLLs Reference each other in a Works
Its a C++ question...
Usually you would simply include a header file from the DLL project to other projects by adding a simple #include statement in your code.
For link, you will need to add the path for the DLL and the DLL name in Project settings->linker page
Note that on Windows, you will probably need to declare your classes with the declspec keyword (Windows only)
https://msdn.microsoft.com/en-us/library/a90k134d.aspx
Eran
Usually you would simply include a header file from the DLL project to other projects by adding a simple #include statement in your code.
For link, you will need to add the path for the DLL and the DLL name in Project settings->linker page
Note that on Windows, you will probably need to declare your classes with the declspec keyword (Windows only)
https://msdn.microsoft.com/en-us/library/a90k134d.aspx
Eran
Make sure you have read the HOW TO POST thread
- ColleenKobe
- CodeLite Expert
- Posts: 130
- Joined: Wed Mar 30, 2016 4:31 pm
- Genuine User: Yes
- IDE Question: C++
- Contact:
Re: How to Make Project DLLs Reference each other in a Works
Thank you for the suggestions, eranif.
Actually, even before you answered, I did (and still do) have an #include statement for the header files declaring the values that give me error messages ("undefined reference to 'x'). I do declare __declspec. I do have paths declared in "Global Settings" for all projects, showing where the library and files reside, and I am sure the files are IN there. I have set up my main program with the sequence of how to compile the projects: the utility dll that everyone depends on first, then the other projects, with the main program last. So I have already tried everything you have suggested, and I still can't get gcc to find my global variables.
I'm sorry. I know you could not have known any of this because I did not post any code. I did not post code because I didn't want to overwhelm you with too much information.
Here is more information about my workspace. Note: here are the real names of my projects, and what they reference.
"utilitiesandglobaldata" compiles and builds just fine.
I'll give you all the info I think might be helpful for ONE project, dfvint, as an example.
For starters, here is the source code.
H File
C File
Here is a screen shot for the dfvint Project Properties:
Here is a screen shot showing the build order for main:
And last, here is the result of "Build Workspace". The resulting file is more than 10K lines long, mostly due to compiler warnings about deprecated function calls. I would sure love to know how to get rid of those messages, without losing other more important messages!
Note: the only dll that this build produced was a utilitiesandglobaldata.dll.
I am still stuck. I have tried a lot of different approaches to make the projects dependent on a utility dll to actually link correctly to the utility dll. Nothing I tried worked. I can write up a list of everything I've tried, but that will make my next posting lengthy.
To summarize:
1. The projects referencing the utility project, never find the utility project information that they need.
2. The projects are not compiling in the "Build Order" sequence that I specified for the main program. I did not submit values for the "Build Order" for the other projects. Should I have?
Is there a way to add a "resource" to my utility project? I am using CodeLite 9.2.0 and I don't see where to add a resource. I am going to try adding my utility dll to the project resources. Maybe then, gcc will find the missing declarations.
------------------
Software Versions:
------------------
CodeLite: 9.2.0 Downloaded from web site.
gcc: 4.9.3
tdm-gcc: 5.1.0.3
Windows 7: 6.1
wxCrafter: 2.5
wxWidgets: 3.1.0
Target build: debug
Target platform: 32-bit
Actually, even before you answered, I did (and still do) have an #include statement for the header files declaring the values that give me error messages ("undefined reference to 'x'). I do declare __declspec. I do have paths declared in "Global Settings" for all projects, showing where the library and files reside, and I am sure the files are IN there. I have set up my main program with the sequence of how to compile the projects: the utility dll that everyone depends on first, then the other projects, with the main program last. So I have already tried everything you have suggested, and I still can't get gcc to find my global variables.
I'm sorry. I know you could not have known any of this because I did not post any code. I did not post code because I didn't want to overwhelm you with too much information.
Here is more information about my workspace. Note: here are the real names of my projects, and what they reference.
Code: Select all
Project Name Description
------------ ---------------------------------
dfvint References utilitiesandglobaldata.
dfvproc References utilitiesandglobaldata.
dfvset References utilitiesandglobaldata.
main Main program. References utilitiesandglobaldata, dfvint, dfvproc, and dfvset.
utilitiesandglobaldata Utilities and global data. Does not reference any other project.
I'll give you all the info I think might be helpful for ONE project, dfvint, as an example.
For starters, here is the source code.
H File
Code: Select all
#ifndef DFVINT_H
#define DFVINT_H
#include <windef.h> // This command must appear BEFORE the
// following commands (if applicable):
// #include winnt.h
// #define CALL_TYPE __stdcall
// Make sure functions are exported with C linkage under C++ compilers.
#ifdef __cplusplus
extern "C"
{ // Export the following code with C linkage.
#endif // Notice that this block is still open. It is closed below.
#define DllExport __declspec(dllexport)
#define DllImport __declspec(dllimport)
#define CALL_TYPE __stdcall
#ifndef UNICODE
#define UNICODE
#endif
#include <winbase.h>
#include "gmem.h"
#include "ut.h"
// =============================================================================
// Global Variables
// =============================================================================
extern Int8 dfvint_X;
extern UInt16 dfvint_Y;
extern WORD dfvint_Z;
// =============================================================================
// dfvint_Read_Loop is run from within a thread, which is why its
// declaration is different from the other procedures and functions.
extern DWORD WINAPI dfvint_Thread (void); // our Thread. :-D
extern DllExport long CALL_TYPE dfvint_Initialize (void);
extern DllExport long CALL_TYPE dfvint_Terminate (void);
//====================
#ifdef __cplusplus
} // Export the following code with C linkage.
#endif
#endif // DFVINT_H
Code: Select all
#include <windef.h> // This command must appear BEFORE the
// following commands (if applicable):
// #include winnt.h
// #define CALL_TYPE __stdcall
// Make sure functions are exported with C linkage under C++ compilers.
#ifdef __cplusplus
extern "C"
{ // Export the following code with C linkage.
#endif // Notice that this block is still open. It is closed below.
#define DllExport __declspec(dllexport)
#define DllImport __declspec(dllimport)
#define CALL_TYPE __stdcall
#ifndef UNICODE
#define UNICODE
#endif
#include "printmsgs.h" // Compiler debug print statement controller.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h> // Only including stdarg.h to cover
// definition of va_list in winbase.h.
#include <winbase.h>
#include "gmem.h"
#include "ut.h"
#include "utilitiesandglobaldata.h"
#include "dfvint.h"
// =============================================================================
// Global Variable Declarations. Defined as "extern" in dfvint.h.
// =============================================================================
Int8 dfvint_X;
UInt16 dfvint_Y;
WORD dfvint_Z;
// *****************************************************************************
DWORD WINAPI dfvint_Thread (void) // our Thread. :-D
{ // dfvint_Thread_Proc
return (1); // for now.
} // dfvint_Thread_Proc
// *****************************************************************************
DllExport long CALL_TYPE dfvint_Initialize (void)
{
long rc = TRUE;
// -------------------------------------------------------------------------
ut_Entering (g_STDOUT, "dfvint_Initialize");
ut_Display_Always (g_STDOUT, " dfvint_Initialize: Well, here we are. Now what?");
dfvint_X = -8;
dfvint_Y = 16;
dfvint_Z = 0xFF;
ut_Exiting (g_STDOUT, "dfvint_Initialize");
return (rc);
} // dfvint_Initialize
// *****************************************************************************
DllExport long CALL_TYPE dfvint_Terminate (void)
{
long rc = TRUE;
// -------------------------------------------------------------------------
ut_Entering (g_STDOUT, "dfvint_Terminate");
ut_Display_Always (g_STDOUT, " dfvint_Terminate: Well, here we are. Now what?");
ut_Exiting (g_STDOUT, "dfvint_Terminate");
return (rc);
} // dfvint_Terminate
// -----------------------------------------------------------------------------
#ifdef __cplusplus
} // Export the preceding code with C linkage.
#endif
Here is a screen shot showing the build order for main:
And last, here is the result of "Build Workspace". The resulting file is more than 10K lines long, mostly due to compiler warnings about deprecated function calls. I would sure love to know how to get rid of those messages, without losing other more important messages!
Note: the only dll that this build produced was a utilitiesandglobaldata.dll.
I am still stuck. I have tried a lot of different approaches to make the projects dependent on a utility dll to actually link correctly to the utility dll. Nothing I tried worked. I can write up a list of everything I've tried, but that will make my next posting lengthy.
To summarize:
1. The projects referencing the utility project, never find the utility project information that they need.
2. The projects are not compiling in the "Build Order" sequence that I specified for the main program. I did not submit values for the "Build Order" for the other projects. Should I have?
Is there a way to add a "resource" to my utility project? I am using CodeLite 9.2.0 and I don't see where to add a resource. I am going to try adding my utility dll to the project resources. Maybe then, gcc will find the missing declarations.
------------------
Software Versions:
------------------
CodeLite: 9.2.0 Downloaded from web site.
gcc: 4.9.3
tdm-gcc: 5.1.0.3
Windows 7: 6.1
wxCrafter: 2.5
wxWidgets: 3.1.0
Target build: debug
Target platform: 32-bit
You do not have the required permissions to view the files attached to this post.
- eranif
- CodeLite Plugin
- Posts: 6375
- Joined: Wed Feb 06, 2008 9:29 pm
- Genuine User: Yes
- IDE Question: C++
- Contact:
Re: How to Make Project DLLs Reference each other in a Works
g_STDOUT is used in the "C" file, but it not defined anywhere ... (at least in the H file you pasted here, nor in the "C" file)
Eran
Eran
Make sure you have read the HOW TO POST thread
- ColleenKobe
- CodeLite Expert
- Posts: 130
- Joined: Wed Mar 30, 2016 4:31 pm
- Genuine User: Yes
- IDE Question: C++
- Contact:
Re: How to Make Project DLLs Reference each other in a Works
You are correct, Eranif. g_STDOUT is a variable declared in utilitiesandglobaldata.dll. utilitiesandglobaldata is the dll I am trying to reference when I build project dfvint.
g_STDOUT is declared in gmem.h as "extern". I do include gmem.h in project dfvint. But I do not include gmem.c in project dfvint, because then I wouldn't be including gmem data as a dll.
Other things declared utilitiesandglobaldata.dll are procedures ut_Entering and ut_Exiting.
Curiously, I don't get error messages for ut_Entering and ut_Exiting.
Running Dependency Walker (http://www.dependencywalker.com/) on utilitiesandglobaldata.dll, I do see ut_Entering and ut_Exiting appear correctly in the dll. But I don't see g_STDOUT. Then again, I don't think Dependency Walker displays variables. Just procedures and functions.
Could it be that the linker can't set up code to directly reference variables stored in a dll? That I can only get variables in a dll via function and procedure calls? Like making a "Set_g_STDOUT" and "Get_g_STDOUT" (which do not currently exist)?
Colleen
g_STDOUT is declared in gmem.h as "extern". I do include gmem.h in project dfvint. But I do not include gmem.c in project dfvint, because then I wouldn't be including gmem data as a dll.
Other things declared utilitiesandglobaldata.dll are procedures ut_Entering and ut_Exiting.
Curiously, I don't get error messages for ut_Entering and ut_Exiting.
Running Dependency Walker (http://www.dependencywalker.com/) on utilitiesandglobaldata.dll, I do see ut_Entering and ut_Exiting appear correctly in the dll. But I don't see g_STDOUT. Then again, I don't think Dependency Walker displays variables. Just procedures and functions.
Could it be that the linker can't set up code to directly reference variables stored in a dll? That I can only get variables in a dll via function and procedure calls? Like making a "Set_g_STDOUT" and "Get_g_STDOUT" (which do not currently exist)?
Colleen