我正在编译用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源文件中定义的。)
但是,我放弃了整个解决方案,因为我找到了一种使用OpenCV
和ffmpeg
从我的IP摄像头获取数据的简单方法。所以我不会再考试了。
谢谢大家的帮助。
答案 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"