未明确引用'功能'来自makefile

时间:2014-11-17 21:41:24

标签: c++

我遇到makefile问题,见下文

// make
....
6-linux-gnu/4.7/crtend.o /usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crtn.o
read_printer_status.o: In function `pal_printer::printer_status()':
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:123: undefined reference to `openUSBDevice(long, long, char const*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:135: undefined reference to `openUSBDevice(long, long, char const*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:149: undefined reference to `GetPrinterStatus(unsigned char*, unsigned long, unsigned long*)'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:156: undefined reference to `closeUSBDevice()'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:179: undefined reference to `closeUSBDevice()'
/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src/read_printer_status.cc:185: undefined reference to `closeUSBDevice()'
collect2: error: ld returned 1 exit status
make: *** [printer2] Error 1

// make -n
root@pc223:/home/adam/Documents/workspace/PALv1/printer/printer2/printer2/src# make -n
g++ -g -Wall -m32 -v -I../include -c printer2.cc -o printer2.o
g++ -g -Wall -m32 -v -I../include -c read_printer_status.cc -o read_printer_status.o
g++ -g -Wall -m32 -v -I../include -c printer2_user.cc -o printer2_user.o
g++ -g -Wall -m32 -v -I../include -o printer2 printer2.o read_printer_status.o printer2_user.o -L../lib -lCeSmLm

我的makefile。我正在使用共享库.so,一些头文件和.cc文件

# Compiler
# for c code: CC = gcc; for c++ code: CC = g++; locate g++
CC = g++

# Compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
# -m32 compiles for 32 bit OS
# -v verbose displays more compiler debugging information
CFLAGS  = -g -Wall -m32 -v

# define any directories containing header files other than /usr/include
INCLUDE = -I../include

# define library paths in addition to /usr/lib
#   if I wanted to include libraries not in /usr/lib I'd specify
#   their path using -Lpath, something like:
LFLAGS= -L../lib

# define any libraries to link into executable:
#   if I want to link in libraries (libx.so or libx.a) I use the -lname
# without lib in front or an extension
LIBS = -lCeSmLm

# define the C source files
SRCS = printer2.cc read_printer_status.cc printer2_user.cc

# define the C object files 
#
# This uses Suffix Replacement within a macro:
#   $(name:string1=string2)
#         For each word in 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .c of all words in the macro SRCS
# with the .o suffix
#
OBJS = $(SRCS:.cc=.o)

# define the executable file 
EXE = printer2

#
# The following part of the makefile is generic; it can be used to 
# build any executable just by changing the definitions above and by
# deleting dependencies appended to the file from 'make depend'
#
.PHONY: depend clean

all: $(EXE)

$(EXE): $(OBJS)
    $(CC) $(CFLAGS) $(INCLUDE) -o $(EXE) $(OBJS) $(LFLAGS) $(LIBS)

# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of
# the rule(a .c file) and $@: the name of the target of the rule (a .o file) 
# (see the gnu make manual section about automatic variables)
.cc.o:
    $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@

clean:
    $(RM) *.o *~ $(EXE)

depend: $(SRCS)
    makedepend $(INCLUDE) $^

CeSmLm.h位于

之下
// Custom Engineering SPA
// USB "interface 0" C library for communication with Custom printers


#ifndef _COM_USB_IF0_CUSTOM_H
#define _COM_USB_IF0_CUSTOM_H 1


#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/time.h>


typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned short BOOL;


//    ---------- 'PUBLIC' FUNCTIONS ----------:

/* This function initialized and opens the USB printer status connection , with the specified parameters.
   Parameters:
   - Vendor ID (int)
   - Product ID (int)
   - Serial Number (constant string)
   Usage example: InitDeviceIf0(0xdd4, 0x01A8, ,TG2480H Num.: 0");
    Note:
    - 1st parameter = -1 : all Vendor IDs will be accepted (be careful!!!) ***
    - 2nd parameter = -1 : all Product IDs will be accepted
    - 3rd parameter = NULL or 'empty string' : all Serial Numbers will be accepted

   Return values:

   - SUCCESS      
   - ERR_NO_INIT
   - ERR_OPEN_DEVICE
   - ERR_ALREADY_OPENED
   - ERR_PARAMINIT_NOT_VALID
*/

DWORD openUSBDevice(long,long,const char*);

/*
   This function the printer status 
   Parameters:
   - buffer to store data in
   - size of the provided buffer
   - return parameter, where the function will store actually read data size

   Return values:
   - ERR_NOT_OPENED
   - ERR_IOCTL_SEND
   - ERR_IOCTL_PIPE
   - ERR_IOCTL_OVERFLOW
   - ERR_IOCTL_LOW_LEVEL
   - ERR_IOCTL_GENERAL
   - ERR_IOCTL_TIMEOUT
   - ERR_READ_BUFFER_FULL
   - ERR_READING_USB
   - SUCCESs

*/

DWORD GetPrinterStatus(unsigned char* bufferRecv,const DWORD dwSize,DWORD* dwRead);


/* This function closes the printer USB status device.
   Return values:
   - ERR_NOT_OPENED
   - ERR_CLOSE
   - SUCCESS
*/

DWORD closeUSBDevice();

#endif    

是对象文件,标题或库的链接问题吗?我不确定。

1 个答案:

答案 0 :(得分:3)

  

&#34;它是与目标文件,标题或库的链接问题?我不确定。&#34;

实际上是c和c ++符号名称的冲突(因此是你提到的所有这些问题的组合问题)。

 // USB "interface 0" C library for communication with Custom printers

这个注释显然表明这个库是纯c,并且链接库中的函数符号名称不会像c ++那样被破坏。
如果您将此标头包含.cpp c ++转换单元并使用g++(vs gcc)进行编译,那么包含的头文件中的声明将被c ++编译器修改为反映它们在符号名称中的参数签名,实际上链接器将使用它们 这是因为c ++允许通过给它们不同的参数集(签名)来重载函数。 c不支持这样的功能,你必须自己使功能名称符号不同。

您正在使用的图书馆并不知道c ++,现代c标题会考虑到与c ++的兼容性,因此需要考虑

extern "C" {
}

阻止所有函数声明。

好吧,你可以通过自己设置这个块来封装#include语句

来解决这个问题
extern "C" {
#include "CeSmLm.h"
}

请参阅此already existing answer,并解释上述内容。每当遇到 undefined reference 链接器错误时,您应该考虑在第1篇中研究答案。