“undefined reference”错误:C头文件,C ++主程序

时间:2016-06-22 13:27:55

标签: c++ c dll

我有一个包含两个项目的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====

提前谢谢!

0 个答案:

没有答案