我有一个包含两个项目的CodeLite工作区。第一个项目包含一个* .c和一个* .h文件。它们包含C语言全局常量,变量和函数。这个项目被编译成一个dll。第二个项目是C ++主程序。它被编译成一个exe。主程序引用变量并调用dll中的函数。
我的问题是我得到变量的“未定义引用”错误消息,但不是常量(#defines)和函数。常量和函数看起来很好。为什么我会为变量获取这些错误,而不是常量和函数?我该如何摆脱错误?
Stack Overflow和CodeLite论坛上有很多帖子来自类似情况的人。当我理解他们的帖子的答案,并且我实施这些帖子的解决方案时,要么他们不解决我的问题,要么让他们变得更糟。
以下是我的文件和其他数据。
软件版本:
CodeLite: 9.1.8
tdm-gcc: 5.1.0.3
Windows 7: 6.1
wxCrafter: 2.5
wxWidgets: 3.1.0
Target platform: 32-bit
Target build: debug
g_memory.c
#include <limits.h>
#include <string.h>
#include "g_memory.h"
// Set Up Compiler Options
#define CALL_TYPE __stdcall
#ifndef UNICODE
#define UNICODE
#endif
int g_Carbon;
char g_Element_Name [g_ST_LENGTH];
int g_Periodic_Table [g_QTY_ELEMENTS];
// *************************************************************************
// G e t _ g _ P e r i o d i c _ T a b l e
// *************************************************************************
DllExport void CALL_TYPE Get_g_Periodic_Table (int New_Values [], int Length)
{
int i = 0;
for (i = 0; i < Length; ++i)
New_Values [i] = g_Periodic_Table [i];
}
DllExport void CALL_TYPE Set_g_Periodic_Table (int New_Values [], int Length)
{
int i = 0;
for (i = 0; i < Length; ++i)
g_Periodic_Table [i] = New_Values [i];
}
// *************************************************************************
// G e t _ g _ E l e m e n t _ N a m e
// *************************************************************************
// DllExport char CALL_TYPE Get_g_Element_Name (void) { return (g_Element_Name); }
// DllExport void CALL_TYPE Set_g_Element_Name (char * New_Value) { g_Element_Name = New_Value; }
//
// char g_Element_Name [g_ST_LENGTH];
// *************************************************************************
G e t _ g _ C a r b o n
// *************************************************************************
DllExport int CALL_TYPE Get_g_Carbon (void) { return (g_Carbon); }
DllExport void CALL_TYPE Set_g_Carbon (int New_Value) { g_Carbon = New_Value; }
// *************************************************************************
// g _ S u m
// *************************************************************************
DllExport int CALL_TYPE g_Sum (int n1, int n2)
{
int Sum = 0;
long long l_Sum = 0;
l_Sum = (long long) n1 + (long long) n2;
if ((l_Sum < INT_MIN) || (INT_MAX < l_Sum))
Sum = 0; // out of range = true
else
Sum = (int) l_Sum; // sum is in range
return (Sum);
}
// *************************************************************************
// g _ I n i t i a l i z e
// *************************************************************************
DllExport int CALL_TYPE g_Initialize (int *g_Carbon,
char g_Element_Name [],
int Debug_ST_LENGTH,
int g_Periodic_Table [],
int Periodic_Table_Length)
{
int i = 0;
*g_Carbon = 3;
memset (g_Element_Name, '\0', Debug_ST_LENGTH);
strcpy (g_Element_Name, "abc");
for (i = 0; i < Periodic_Table_Length; ++i)
g_Periodic_Table [i] = i * 2 + 6;
return ((int) g_ZERO);
}
g_memory.h
#ifndef G_MEMORY_H
#define G_MEMORY_H
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
#define CALL_TYPE __stdcall
#define g_ST_LENGTH 255
#define g_QTY_ELEMENTS 5
#define g_ZERO 0
// Variable declarations. ------------------------------------------------------
extern int g_Carbon;
extern char g_Element_Name [g_ST_LENGTH];
extern int g_Periodic_Table [g_QTY_ELEMENTS];
// Function declarations. ------------------------------------------------------
#ifdef __cplusplus
extern "C"
{
#endif // begin C-language declarations
extern DllExport int CALL_TYPE g_Sum (int n1, int n2);
extern DllExport int CALL_TYPE g_Initialize (int *g_Carbon,
char g_Element_Name [],
int Debug_ST_LENGTH,
int g_Periodic_Table [],
int Periodic_Table_Length);
extern DllExport void CALL_TYPE Get_g_Periodic_Table (int New_Values [], int Length);
extern DllExport void CALL_TYPE Set_g_Periodic_Table (int New_Values [], int Length);
extern DllExport int CALL_TYPE Get_g_Carbon (void);
extern DllExport void CALL_TYPE Set_g_Carbon (int New_Value);
#ifdef __cplusplus
}
#endif // end of C-language declarations
#endif // G_MEMORY_H
的main.cpp
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "g_memory.h"
int main(int argc, char **argv)
{
int A1 = g_ZERO;
int A2 = g_ZERO;
int i = g_ZERO;
int rc = g_ZERO;
int Sum = g_ZERO;
int local_Periodic_Table [g_QTY_ELEMENTS];
printf("You're doing great!!!\n");
// -------------------------------------------------------------------------
// Part 1: Testing the Variables and #defines.
// -------------------------------------------------------------------------
Set_g_Carbon (g_ZERO);
printf("\nAFTER STEP 1: global variable g_Carbon = %d (should be 0).\n", Get_g_Carbon());
rc = g_Initialize (&g_Carbon,
g_Element_Name,
g_ST_LENGTH,
g_Periodic_Table,
g_QTY_ELEMENTS);
printf("\nAFTER STEP 2: rc from g_Initialize = %d; global variable g_Carbon = %d (should be 3).\n", rc, Get_g_Carbon());
for (i = 0; i < g_QTY_ELEMENTS; ++i)
{
local_Periodic_Table [i] = g_QTY_ELEMENTS - i;
printf (" local_Periodic_Table [%d] = %d.\n", i, local_Periodic_Table [i]);
}
// Set the global array to the contents of the local array.
Set_g_Periodic_Table(local_Periodic_Table, g_QTY_ELEMENTS);
for (i = 0; i < g_QTY_ELEMENTS; ++i)
{
g_Periodic_Table [i] = g_QTY_ELEMENTS - i;
printf (" g_Periodic_Table [%d] = %d.\n", i, g_Periodic_Table [i]);
}
// Set the global array to the contents of the local array.
Set_g_Periodic_Table(local_Periodic_Table, g_QTY_ELEMENTS);
memset (local_Periodic_Table, 0, sizeof(int) * g_QTY_ELEMENTS); // Clear the local array.
printf ("\nAfter clearing local_Periodic_Table to g_ZERO, here's what's in it:\n");
for (i = 0; i < g_QTY_ELEMENTS; ++i)
{
printf (" local_Periodic_Table [%d] = %d.\n", i, local_Periodic_Table [i]);
}
// Put the global array contents into the local array.
Get_g_Periodic_Table(local_Periodic_Table, g_QTY_ELEMENTS);
printf ("\nAfter loading local_Periodic_Table with the contents of g_Periodic_Table, here's what's in local_Periodic_Table:\n");
for (i = 0; i < g_QTY_ELEMENTS; ++i)
{
printf (" local_Periodic_Table [%d] = %d.\n", i, local_Periodic_Table [i]);
}
Set_g_Carbon (7);
printf("\nAFTER STEP 3: global variable g_Carbon = %d (should be 7).\n", Get_g_Carbon());
Set_g_Carbon (Get_g_Carbon() + 4);
printf("\nAFTER STEP 4: global variable g_Carbon = %d (should be 11).\n", Get_g_Carbon());
// g_Element_Name [0] = 'o';
// g_Element_Name [1] = 'k';
// g_Element_Name [2] = '!';
// g_Element_Name [3] = '\0';
// printf("\n\nglobal variable g_Element_Name = <%s>.\n\n", g_Element_Name);
// fflush(stdout);
// Part 2: Testing the function calls.
A1 = 5;
A2 = 11;
printf ("--- Ordinary Math Check -------------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
// Underflow check 1: the sum == Minimum value (valid)
//
// ---O==================================|---
// min max
A1 = -INT_MAX;
A2 = -1;
printf ("--- Underflow Check 1: valid --------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
// Underflow check 2: the sum < Minimum value (invalid)
//
// --O|==================================|---
// min max
A2 = -2;
printf ("--- Underflow Check 2: invalid ------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
// Overflow check 1: the sum == Maximum value (valid)
//
// ---|==================================O---
// min max
A1 = INT_MAX;
A2 = 1;
printf ("--- Overflow Check 1: valid ---------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
// Overflow check 2: the sum > Maximum value (invalid)
//
// ---|==================================|O--
// min max
A2 = 2;
printf ("--- Overflow Check 2: invalid -------------------------------\n");
Sum = g_Sum(A1, A2);
printf("%d + %d = %d\n\n", A1, A2, Sum);
fflush(stdout);
return 0;
}
编译和链接的结果
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/GlobalVariableTests2/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/GlobalVariableTests2/MainProg/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I../include/ -I.
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/GlobalVariableTests2/MainProg/main.cpp:29: undefined reference to `g_Periodic_Table'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests2/MainProg/main.cpp:29: undefined reference to `g_Element_Name'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests2/MainProg/main.cpp:29: undefined reference to `g_Carbon'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests2/MainProg/main.cpp:44: undefined reference to `g_Periodic_Table'
F:/Prototypes_CPP_Console_Only/GlobalVariableTests2/MainProg/main.cpp:45: undefined reference to `g_Periodic_Table'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe: *** [../RunFromHere/MainProg] Error 1
MainProg.mk:81: recipe for target '../RunFromHere/MainProg' failed
====5 errors, 0 warnings====
提前谢谢!