简体   繁体   English

对同一文件中定义的函数的未定义引用

[英]Undefined reference to a function defined in the same file

I am compiling a code generated with gsoap, and I should compile some files provided by gsoap in /usr/share/gsoap/plugin/ too. 我正在编译使用gsoap生成的代码,我也应该在/usr/share/gsoap/plugin/编译gsoap提供的一些文件。

The problem is that in linking step, I get undefined reference error: 问题是在链接步骤中,我得到未定义的参考错误:

wsseapi.o: In function `soap_wsse_verify_Timestamp':
wsseapi.cpp:(.text+0xf64): undefined reference to `soap_wsa_sender_fault_subcode'

... and a lot more to the same symbol. ……还有更多相同的符号。

The symbol however is defined in the same file as soap_wsse_verify_Timestamp that uses it and when I check the object file with readelf, the symbol is defined in it: 但是,该符号与使用它的soap_wsse_verify_Timestamp在同一文件中soap_wsse_verify_Timestamp ,并且当我使用readelf检查目标文件时,在其中定义了该符号:

$ readelf -Ws wsseapi.o |grep soap_wsa_sender_fault_subcode
   164: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND soap_wsa_sender_fault_subcode

Here is the function definitions in the original file: 这是原始文件中的函数定义:

/**
@fn int soap_wsse_verify_Timestamp(struct soap *soap)
@brief Verifies the Timestamp/Expires element against the current time.
@param soap context
@return SOAP_OK or SOAP_FAULT with wsse:FailedAuthentication fault

Sets wsse:FailedAuthentication fault if wsu:Timestamp is expired. The
SOAP_WSSE_CLKSKEW value is used as a margin to mitigate clock skew. Keeps
silent when no timestamp is supplied or no expiration date is included in the
wsu:Timestamp element.
*/
int
soap_wsse_verify_Timestamp(struct soap *soap)
{ _wsu__Timestamp *timestamp = soap_wsse_Timestamp(soap);
  DBGFUN("soap_wsse_verify_Timestamp");
  /* if we have a timestamp with an expiration date, check it */
  if (timestamp && timestamp->Expires)
  { time_t now = time(NULL), expired;
    soap_s2dateTime(soap, timestamp->Expires, &expired);
    if (expired + SOAP_WSSE_CLKSKEW <= now)
    { const char *code = soap_wsu__tTimestampFault2s(soap, wsu__MessageExpired);
      return soap_wsse_sender_fault_subcode(soap, code, "Message has expired", timestamp->Expires);
    }
  }
  return SOAP_OK;
}

and

/**
@fn int soap_wsse_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
@brief Sets sender SOAP Fault (sub)code for server fault response.
@param soap context
@param[in] faultsubcode sub code string
@param[in] faultstring fault string
@param[in] faultdetail detail string
@return SOAP_FAULT
*/
int
soap_wsse_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
{
#if defined(SOAP_WSA_2003) || defined(SOAP_WSA_2004) || defined(SOAP_WSA_200408) || defined(SOAP_WSA_2005)
  return soap_wsa_sender_fault_subcode(soap, faultsubcode, faultstring, faultdetail);
#else
  return soap_sender_fault_subcode(soap, faultsubcode, faultstring, faultdetail);
#endif
}

finally, 最后,

/**
@fn int soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
@brief Sets sender SOAP Fault (sub)code for server fault response.
@param soap context
@param[in] faultsubcode sub code string
@param[in] faultstring fault string
@param[in] faultdetail detail string
@return SOAP_FAULT
*/
int
soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
{ return soap_wsa_fault_subcode(soap, 1, faultsubcode, faultstring, faultdetail);
}

My question is how can an undefined reference error occur when the symbol is defined in the same file and can be find in the same object file. 我的问题是,当符号在同一文件中定义并且可以在同一目标文件中找到时,如何发生未定义的引用错误。

Thanks. 谢谢。

EDIT: Here is the definition part in a header file included in the top of the cpp file: 编辑:这是cpp文件顶部包含的头文件中的定义部分:

int soap_wsa_request(struct soap *soap, const char *id, const char *to, const char *action);
int soap_wsa_add_From(struct soap *soap, const char *endpoint);
int soap_wsa_add_NoReply(struct soap *soap);
int soap_wsa_add_ReplyTo(struct soap *soap, const char *endpoint);
int soap_wsa_add_FaultTo(struct soap *soap, const char *endpoint);
int soap_wsa_add_RelatesTo(struct soap *soap, const char *endpoint);
const char *soap_wsa_From(struct soap *soap);
const char *soap_wsa_ReplyTo(struct soap *soap);
const char *soap_wsa_FaultTo(struct soap *soap);
const char *soap_wsa_RelatesTo(struct soap *soap);

int soap_wsa_check(struct soap *soap);
int soap_wsa_reply(struct soap *soap, const char *id, const char *action);
int soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail);
int soap_wsa_fault_subcode_action(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail, const char *action);
int soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail);
int soap_wsa_sender_fault_subcode_action(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail, const char *action);
int soap_wsa_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail);
int soap_wsa_receiver_fault_subcode_action(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail, const char *action);
int soap_wsa_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail);
int soap_wsa_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail);

UPDATE: The problem seems to be due the linking problem between C++ and C (As you can see in the answers). 更新:问题似乎是由于C ++和C之间的链接问题(如您在答案中所见)。 And there's a paradox in gsoap files, because there's an autogenerated header file being used in a C source, wsseapi.c which uses C++ features. gsoap文件中存在一个矛盾之处,因为在C源代码中使用了自动生成的头文件wsseapi.c ,该文件使用了C ++功能。 If I could solve this problem, then I think compiling and linking wsseapi.c as well could fix the problem (As someone in the comments mentioned, the missing function is actually defined in the C source file.) 如果我可以解决此问题,那么我认为编译和链接wsseapi.c也可以解决该问题(正如评论中提到的某人所述,缺少的功能实际上是在C源文件中定义的。)

However, I am giving up in this whole solution, because I have found a simpler way to get data from my IP camera using OpenCV and ffmpeg . 但是,我放弃了整个解决方案,因为我找到了使用OpenCVffmpeg从IP摄像机获取数据的更简单方法。 So I'm not gonna test anymore. 所以我不再测试了。

Thank you all for helping. 谢谢大家的帮助。

The problem I suspect is that you are trying to link some C code with C++. 我怀疑的问题是您正在尝试将某些C代码与C ++链接。 This can lead to linking errors caused by how names are mangled in C++ compared to C. 与C相比,这可能导致由C ++中的名称修饰方式引起的链接错误。

To resolve such issues you should wrap the functions that are compiled from a C source file in an extern scope: 要解决此类问题,您应该将从C源文件编译的函数包装在extern范围内:

extern "C" {
  int soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail);
}

This would prevent the enclosed functions to be mangled so that their reference in the object file can be correctly found and linked. 这样可以防止封闭的函数被破坏,从而可以正确找到并链接它们在目标文件中的引用。 You can find additional information here . 您可以在此处找到更多信息。

This problem occurred because you tried to link C code with C++ code. 发生此问题,因为您试图将C代码与C ++代码链接。

Let's say you have wssapi.c wssapi.h main.cpp . 假设您有wssapi.c wssapi.h main.cpp In your main.cpp do this 在您的main.cpp执行此操作

extern "C" {
    #include "wssapi.h"
}

Instead of only 不仅仅是

#include "wssapi.h"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM