My problem is that I get "undefined reference" linker error messages for the variables, but not for the constants (#defines) and functions. The constants and functions appear to be fine. How do I get rid of the error messages for the global variables?
Here are my files and other data.
g_memory.c
Code: Select all
#include "g_memory.h"
#include "string.h"
// Set Up Compiler Options
#define CALL_TYPE __stdcall
#ifndef UNICODE
#define UNICODE
#endif
int g_banana;
char g_Debug_Filename [g_FILENAME_LENGTH];
int g_fruitbasket [g_QTY_FRUITS];
// *************************************************************************
// S e t a n d G e t g _ f r u i t b a s k e t
// *************************************************************************
DllExport void CALL_TYPE Get_g_fruitbasket (int New_Values [], int Length)
{
int i = 0;
for (i = 0; i < Length; ++i)
New_Values [i] = g_fruitbasket [i];
}
DllExport void CALL_TYPE Set_g_fruitbasket (int New_Values [], int Length)
{
int i = 0;
for (i = 0; i < Length; ++i)
g_fruitbasket [i] = New_Values [i];
}
// *************************************************************************
// S e t a n d G e t g _ x
// *************************************************************************
// DllExport char CALL_TYPE Get_g_Debug_Filename (void) { return (g_Debug_Filename); }
// DllExport void CALL_TYPE Set_g_Debug_Filename (char * New_Value) { g_Debug_Filename = New_Value; }
//
// char g_Debug_Filename [g_FILENAME_LENGTH];
// // *************************************************************************
// // S e t a n d G e t g _ b a n a n a
// // *************************************************************************
DllExport int CALL_TYPE Get_g_banana (void) { return (g_banana); }
DllExport void CALL_TYPE Set_g_banana (int New_Value) { g_banana = New_Value; }
// *************************************************************************
// g _ S u m
// *************************************************************************
DllExport int CALL_TYPE g_Sum (int addend1, int addend2)
{
double actual_sum = g_ZERO;
int rc = g_ZERO;
// Check for overflow and underflow. If the sum is in range, return it.
// Otherwise, return g_ZERO.
actual_sum = (double) ((double) addend1 + (double) addend2);
if (actual_sum < (double) g_INT_MIN)
rc = g_ZERO;
else if ((double) g_INT_MAX < actual_sum)
rc = g_ZERO;
else
rc = actual_sum;
return (rc);
}
// *************************************************************************
// g _ I n i t i a l i z e
// *************************************************************************
DllExport int CALL_TYPE g_Initialize (int *g_banana,
char g_Debug_Filename [],
int Debug_Filename_Length,
int g_fruitbasket [],
int fruitbasket_Length)
{
int i = 0;
*g_banana = 3;
memset (g_Debug_Filename, '\0', Debug_Filename_Length);
strcpy (g_Debug_Filename, "abc");
for (i = 0; i < fruitbasket_Length; ++i)
g_fruitbasket [i] = i * 2 + 6;
return ((int) g_ZERO);
}
Code: Select all
#ifndef G_MEMORY_H
#define G_MEMORY_H
#ifdef __cplusplus
extern "C"
{
#endif
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
#define CALL_TYPE __stdcall
#define g_FILENAME_LENGTH 255
#define g_INT_MAX 2147483648
#define g_INT_MIN -2147483647
#define g_QTY_FRUITS 5
#define g_ZERO 0
extern int g_banana;
extern char g_Debug_Filename [g_FILENAME_LENGTH];
extern int g_fruitbasket [g_QTY_FRUITS];
extern DllExport int CALL_TYPE g_Sum (int addend1, int addend2);
extern DllExport int CALL_TYPE g_Initialize (int *g_banana,
char g_Debug_Filename [],
int Debug_Filename_Length,
int g_fruitbasket [],
int fruitbasket_Length);
extern DllExport void CALL_TYPE Get_g_fruitbasket (int New_Values [], int Length);
extern DllExport void CALL_TYPE Set_g_fruitbasket (int New_Values [], int Length);
extern DllExport int CALL_TYPE Get_g_banana (void);
extern DllExport void CALL_TYPE Set_g_banana (int New_Value);
#ifdef __cplusplus
}
#endif
#endif // G_MEMORY_H
Code: Select all
#include <stdio.h>
#include <string.h>
#include "g_memory.h"
int main(int argc, char **argv)
{
int i = g_ZERO;
int A1 = g_ZERO;
int A2 = g_ZERO;
int rc = g_ZERO;
int Sum = g_ZERO;
int local_fruitbasket [g_QTY_FRUITS];
printf("You're doing great!!!\n");
// -------------------------------------------------------------------------
// Part 1: Testing the Variables and #defines.
// -------------------------------------------------------------------------
Set_g_banana (g_ZERO);
printf("\nAFTER STEP 1: global variable g_banana = %d (should be 0).\n", Get_g_banana());
rc = g_Initialize (&g_banana,
g_Debug_Filename,
g_FILENAME_LENGTH,
g_fruitbasket,
g_QTY_FRUITS);
printf("\nAFTER STEP 2: rc from g_Initialize = %d; global variable g_banana = %d (should be 3).\n", rc, Get_g_banana());
for (i = 0; i < g_QTY_FRUITS; ++i)
{
local_fruitbasket [i] = g_QTY_FRUITS - i;
printf (" local_fruitbasket [%d] = %d.\n", i, local_fruitbasket [i]);
}
Set_g_fruitbasket(local_fruitbasket, g_QTY_FRUITS); // Set the global array to the contents of the local array.
memset (local_fruitbasket, 0, sizeof(int) * g_QTY_FRUITS); // Clear the local array.
printf ("\nAfter clearing local_fruitbasket to g_ZERO, here's what's in it:\n");
for (i = 0; i < g_QTY_FRUITS; ++i)
{
printf (" local_fruitbasket [%d] = %d.\n", i, local_fruitbasket [i]);
}
Get_g_fruitbasket(local_fruitbasket, g_QTY_FRUITS); // Put the global array contents into the local array.
printf ("\nAfter loading local_fruitbasket with the contents of g_fruitbasket, here's what's in local_fruitbasket:\n");
for (i = 0; i < g_QTY_FRUITS; ++i)
{
printf (" local_fruitbasket [%d] = %d.\n", i, local_fruitbasket [i]);
}
Set_g_banana (7);
printf("\nAFTER STEP 3: global variable g_banana = %d (should be 7).\n", Get_g_banana());
Set_g_banana (Get_g_banana() + 4);
printf("\nAFTER STEP 4: global variable g_banana = %d (should be 11).\n", Get_g_banana());
// g_Debug_Filename [0] = 'o';
// g_Debug_Filename [1] = 'k';
// g_Debug_Filename [2] = '!';
// g_Debug_Filename [3] = '\0';
// printf("\n\nglobal variable g_Debug_Filename = <%s>.\n\n", g_Debug_Filename);
// Part 2: Testing the function calls.
fflush(stdout);
A1 = 5;
A2 = 11;
printf ("-------------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
A1 = g_INT_MIN + 1;
A2 = -1;
printf ("--- Underflow Check 1 ---------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
A1 = g_INT_MIN + 1;
A2 = -2;
printf ("--- Underflow Check 2 ---------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
A1 = g_INT_MAX - 1;
A2 = 1;
printf ("--- Overflow Check 1 ----------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
A1 = g_INT_MAX - 1;
A2 = 2;
printf ("--- Overflow Check 2 ----------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
fflush(stdout);
return 0;
}
Code: Select all
C:\Windows\system32\cmd.exe /C C:/TDM-GCC-32/bin/mingw32-make.exe -e -f "Globals.mk" MakeIntermediateDirs && C:/TDM-GCC-32/bin/mingw32-make.exe -e -f "Globals.mk" all
----------Building project:[ Globals - Debug ]----------
C:/TDM-GCC-32/bin/gcc.exe -c "F:/Prototypes_CPP_Console_Only/GlobalVariableTests/Globals/g_memory.c" -g -O0 -Wall -o ./Debug/g_memory.c.o -I. -I../include/ -I. -I../include/
gcc -shared -fPIC -o ../RunFromHere/Globals.dll @"Globals.txt" -L. -L../RunFromHere/
====0 errors, 0 warnings====
C:\Windows\system32\cmd.exe /C C:/TDM-GCC-32/bin/mingw32-make.exe -e -f "MainProg.mk" MakeIntermediateDirs && C:/TDM-GCC-32/bin/mingw32-make.exe -e -f "MainProg.mk" all
----------Building project:[ MainProg - Debug ]----------
C:/TDM-GCC-32/bin/g++.exe -c "F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I../include/ -I.
F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp:90:5: warning: this decimal constant is unsigned only in ISO C90
A1 = g_INT_MAX - 1;
^
F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp:96:5: warning: this decimal constant is unsigned only in ISO C90
A1 = g_INT_MAX - 1;
^
C:/TDM-GCC-32/bin/mingw32-g++.exe -o ../RunFromHere/MainProg @"MainProg.txt" -L. -L../RunFromHere/ -L. -L../RunFromHere/ -lGlobals
./Debug/main.cpp.o: In function `main':
F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp:29: undefined reference to `g_fruitbasket'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp:29: undefined reference to `g_Debug_Filename'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests/MainProg/main.cpp:29: undefined reference to `g_banana'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe: *** [../RunFromHere/MainProg] Error 1
MainProg.mk:81: recipe for target '../RunFromHere/MainProg' failed
====3 errors, 2 warnings====
Code: Select all
CodeLite: 9.1.8
gcc: 4.9.3
tdm-gcc: 5.1.0.3
Windows 7: 6.1
wxCrafter: 2.5
wxWidgets: 3.1.0
Target platform: 32-bit
Target build: debug
Thank you in advance!!!