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

时间:2015-12-23 16:02:36

标签: c++ linker undefined-reference gsoap

我正在编译用gsoap生成的代码,我也应该在/usr/share/gsoap/plugin/中编译gsoap提供的一些文件。

问题是在链接步骤中,我得到未定义的引用错误:

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

......还有更多相同的符号。

然而,符号在与使用它的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

以下是原始文件中的函数定义:

/**
@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;
}

/**
@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
}

最后,

/**
@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);
}

我的问题是,当符号在同一个文件中定义并且可以在同一个目标文件中找到时,如何发生未定义的引用错误。

感谢。

修改 这是包含在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);

更新 这个问题似乎是由于C ++和C之间的链接问题(正如你在答案中看到的那样)。并且在gsoap文件中存在一个悖论,因为在C源代码中使用了自动生成的头文件,wsseapi.c使用了C ++功能。如果我能解决这个问题,那么我认为编译和链接wsseapi.c也可以解决问题(正如提到的评论中的某些人,缺少的函数实际上是在C源文件中定义的。)

但是,我放弃了整个解决方案,因为我找到了一种使用OpenCVffmpeg从我的IP摄像头获取数据的简单方法。所以我不会再考试了。

谢谢大家的帮助。

2 个答案:

答案 0 :(得分:3)

我怀疑的问题是你试图用C ++链接一些C代码。这可能导致链接错误,这些错误是由C ++中的名称与C相比造成的。

要解决此类问题,您应该将从C源文件中编译的函数包装在web范围内:

Route::group(['middleware' => 'web'], function() {
    // Place all your web routes here...
});

这样可以防止封闭的函数被破坏,以便可以正确地找到并链接它们在目标文件中的引用。您可以找到其他信息here

答案 1 :(得分:1)

发生此问题是因为您尝试将C代码与C ++代码链接。

假设您有wssapi.c wssapi.h main.cpp。在main.cpp执行此操作

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

而不仅仅是

#include "wssapi.h"