gpt4 book ai didi

c++ - C++/gSoap 2.8.2 中奇怪的结构成员对齐

转载 作者:太空狗 更新时间:2023-10-29 23:16:56 29 4
gpt4 key购买 nike

我在 C++ 中遇到了一个奇怪的结构成员对齐问题。使用 gSoap 2.8.2 时会发生这种情况。 gSoap 定义了这个结构:

struct SOAP_STD_API soap
{ short state; /* 0 = uninitialized, 1 = initialized, 2 = copy of another soap struct */
short version; /* 1 = SOAP1.1 and 2 = SOAP1.2 (set automatically from namespace URI in nsmap table) */
soap_mode mode;
soap_mode imode;
soap_mode omode;
const char *float_format; /* user-definable format string for floats (<1024 chars) */
const char *double_format; /* user-definable format string for doubles (<1024 chars) */
const char *dime_id_format; /* user-definable format string for integer DIME id (<SOAP_TAGLEN chars) */
const char *http_version; /* HTTP version used "1.0" or "1.1" */
const char *http_content; /* optional custom response content type (with SOAP_FILE) */
const char *encodingStyle; /* default = NULL which means that SOAP encoding is used */
const char *actor; /* SOAP-ENV:actor or role attribute value */
const char *lang; /* xml:lang attribute value of SOAP-ENV:Text */
int recv_timeout; /* when > 0, gives socket recv timeout in seconds, < 0 in usec */
int send_timeout; /* when > 0, gives socket send timeout in seconds, < 0 in usec */
int connect_timeout; /* when > 0, gives socket connect() timeout in seconds, < 0 in usec */
int accept_timeout; /* when > 0, gives socket accept() timeout in seconds, < 0 in usec */
int socket_flags; /* socket recv() and send() flags, e.g. set to MSG_NOSIGNAL to disable sigpipe */
int connect_flags; /* connect() SOL_SOCKET sockopt flags, e.g. set to SO_DEBUG to debug socket */
int bind_flags; /* bind() SOL_SOCKET sockopt flags, e.g. set to SO_REUSEADDR to enable reuse */
int accept_flags; /* accept() SOL_SOCKET sockopt flags */
unsigned short linger_time; /* linger time for SO_LINGER option */
const struct Namespace *namespaces; /* Pointer to global namespace mapping table */
struct Namespace *local_namespaces; /* Local namespace mapping table */
struct soap_nlist *nlist; /* namespace stack */
struct soap_blist *blist; /* block allocation stack */
struct soap_clist *clist; /* class instance allocation list */
void *alist; /* memory allocation (malloc) list */
struct soap_ilist *iht[SOAP_IDHASH];
struct soap_plist *pht[SOAP_PTRHASH];
struct soap_pblk *pblk; /* plist block allocation */
short pidx; /* plist block allocation */
struct SOAP_ENV__Header *header;
struct SOAP_ENV__Fault *fault;
int idnum;
void *user; /* for user to pass user-defined data */
void *data[4]; /* extension data = {smdevp, mecevp, ...} */
struct soap_plugin *plugins; /* linked list of plug-in data */
const char *userid; /* HTTP Basic authorization userid */
const char *passwd; /* HTTP Basic authorization passwd */
int (*fpost)(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
int (*fget)(struct soap*); /* HTTP GET hook (not set by default) */
int (*fput)(struct soap*); /* HTTP PUT hook (handled as POST) */
int (*fdel)(struct soap*); /* HTTP DELETE hook (not set by default) */
int (*fopt)(struct soap*); /* HTTP OPTIONS hook (not set by default) */
int (*fhead)(struct soap*); /* HTTP HEAD hook (not set by default) */
int (*fform)(struct soap*); /* HTTP/HTML form handler for plugins */
int (*fposthdr)(struct soap*, const char*, const char*);
int (*fresponse)(struct soap*, int, size_t);
int (*fparse)(struct soap*);
int (*fparsehdr)(struct soap*, const char*, const char*);
int (*fheader)(struct soap*);
int (*fresolve)(struct soap*, const char*, struct in_addr* inaddr);
int (*fconnect)(struct soap*, const char*, const char*, int);
int (*fdisconnect)(struct soap*);
int (*fclosesocket)(struct soap*, SOAP_SOCKET);
int (*fshutdownsocket)(struct soap*, SOAP_SOCKET, int);
SOAP_SOCKET (*fopen)(struct soap*, const char*, const char*, int);
SOAP_SOCKET (*faccept)(struct soap*, SOAP_SOCKET, struct sockaddr*, int *n);
int (*fclose)(struct soap*);
int (*fsend)(struct soap*, const char*, size_t);
size_t (*frecv)(struct soap*, char*, size_t);
int (*fpoll)(struct soap*);
int (*fselect)(struct soap*, SOAP_SOCKET, int, int, void*);
void *fselect_param;
void (*fseterror)(struct soap*, const char **c, const char **s);
int (*fignore)(struct soap*, const char*);
int (*fserveloop)(struct soap*);
void *(*fplugin)(struct soap*, const char*);
void *(*fmalloc)(struct soap*, size_t);
#ifndef WITH_LEANER
int (*feltbegin)(struct soap*, const char*);
int (*feltendin)(struct soap*, const char*, const char*);
int (*feltbegout)(struct soap*, const char*);
int (*feltendout)(struct soap*, const char*);
int (*fprepareinitsend)(struct soap*);
int (*fprepareinitrecv)(struct soap*);
int (*fpreparesend)(struct soap*, const char*, size_t);
int (*fpreparerecv)(struct soap*, const char*, size_t);
int (*fpreparefinalsend)(struct soap*);
int (*fpreparefinalrecv)(struct soap*);
int filterstop;
int (*ffiltersend)(struct soap*, const char**, size_t*);
int (*ffilterrecv)(struct soap*, char*, size_t*, size_t);
void *(*fdimereadopen)(struct soap*, void*, const char*, const char*, const char*);
void *(*fdimewriteopen)(struct soap*, const char*, const char*, const char*);
void (*fdimereadclose)(struct soap*, void*);
void (*fdimewriteclose)(struct soap*, void*);
size_t (*fdimeread)(struct soap*, void*, char*, size_t);
int (*fdimewrite)(struct soap*, void*, const char*, size_t);
void *(*fmimereadopen)(struct soap*, void*, const char*, const char*, const char*);
void *(*fmimewriteopen)(struct soap*, void*, const char*, const char*, const char*, enum soap_mime_encoding);
void (*fmimereadclose)(struct soap*, void*);
void (*fmimewriteclose)(struct soap*, void*);
size_t (*fmimeread)(struct soap*, void*, char*, size_t);
int (*fmimewrite)(struct soap*, void*, const char*, size_t);
#endif
SOAP_SOCKET master;
SOAP_SOCKET socket;
#if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
std::ostream *os;
std::istream *is;
#else
void *os; /* preserve struct size */
void *is; /* preserve struct size */
#endif
#ifndef UNDER_CE
int sendfd; /* WinCE FD to send */
int recvfd; /* WinCE FD to receive */
#else
FILE *sendfd;
FILE *recvfd;
#endif
size_t bufidx; /* index in soap.buf[] */
size_t buflen; /* length of soap.buf[] content */
soap_wchar ahead; /* parser lookahead */
short cdata; /* CDATA parser state */
short body; /* parsed XML element has a body or not */
unsigned int level; /* XML nesting level */
size_t count; /* message length counter */
size_t length; /* message length as set by HTTP header */
char *labbuf; /* look-aside buffer */
size_t lablen; /* look-aside buffer allocated length */
size_t labidx; /* look-aside buffer index to available part */
char buf[SOAP_BUFLEN];/* send and receive buffer */
char msgbuf[1024]; /* in/out buffer for HTTP/MIME headers >=1024 bytes */
char tmpbuf[1024]; /* in/out buffer for HTTP/MIME headers, simpleType values, element and attribute tag names, and DIME must be >=1024 bytes */
char tag[SOAP_TAGLEN];
char id[SOAP_TAGLEN];
char href[SOAP_TAGLEN];
char type[SOAP_TAGLEN];
char arrayType[SOAP_TAGLEN];
char arraySize[SOAP_TAGLEN];
char arrayOffset[SOAP_TAGLEN];
short other;
short position;
int positions[SOAP_MAXDIMS];
short root;
struct soap_attribute *attributes; /* attribute list */
short encoding; /* when set, output encodingStyle */
short mustUnderstand; /* a mustUnderstand element was parsed or is output */
short null; /* parsed XML is xsi:nil */
short ns; /* when not set, output full xmlns bindings */
short part; /* SOAP part state (header or body) */
short event; /* engine events and states for use by plugins */
short alloced;
short peeked;
size_t chunksize;
size_t chunkbuflen;
char endpoint[SOAP_TAGLEN];
char path[SOAP_TAGLEN];
char host[SOAP_TAGLEN];
char *action;
char *authrealm; /* HTTP authentication realm */
char *prolog; /* XML declaration prolog */
unsigned long ip; /* IP number */
int port; /* port number */
short keep_alive; /* connection should be kept open */
short tcp_keep_alive; /* enable SO_KEEPALIVE */
unsigned int tcp_keep_idle; /* set TCP_KEEPIDLE */
unsigned int tcp_keep_intvl; /* set TCP_KEEPINTVL */
unsigned int tcp_keep_cnt; /* set TCP_KEEPCNT */
unsigned int max_keep_alive; /* maximum keep-alive session (default=100) */
const char *proxy_http_version;/* HTTP version of proxy "1.0" or "1.1" */
const char *proxy_host; /* Proxy Server host name */
int proxy_port; /* Proxy Server port (default = 8080) */
const char *proxy_userid; /* Proxy Authorization user name */
const char *proxy_passwd; /* Proxy Authorization password */
const char *proxy_from; /* X-Forwarding-For header returned by proxy */
int status; /* -1 when request, else error code to be returned by server */
int error;
int errmode;
int errnum;
#ifndef WITH_LEANER
struct soap_dom_element *dom;
struct soap_dime dime;
struct soap_mime mime;
struct soap_xlist *xlist;
#endif
#if !defined(WITH_LEAN) || defined(SOAP_DEBUG)
const char *logfile[SOAP_MAXLOGS];
FILE *fdebug[SOAP_MAXLOGS];
struct soap_mlist *mht[SOAP_PTRHASH];
#endif
#ifndef WITH_LEAN
const char *wsuid; /* space-separated string of element tags */
const char *c14nexclude; /* space-separated string of prefixes */
struct soap_cookie *cookies;
const char *cookie_domain;
const char *cookie_path;
int cookie_max;
#endif
#ifndef WITH_NOIO
int ipv6_multicast_if; /* in6addr->sin6_scope_id IPv6 value */
char* ipv4_multicast_if; /* IP_MULTICAST_IF IPv4 setsockopt interface_addr */
unsigned char ipv4_multicast_ttl; /* IP_MULTICAST_TTL value 0..255 */
#ifdef WITH_IPV6
struct sockaddr_storage peer; /* IPv6: set by soap_accept and by UDP recv */
#else
struct sockaddr_in peer; /* IPv4: set by soap_connect/soap_accept and by UDP recv */
#endif
#endif
size_t peerlen;
#if defined(WITH_OPENSSL) /* OpenSSL */
int (*fsslauth)(struct soap*);
int (*fsslverify)(int, X509_STORE_CTX*);
BIO *bio;
SSL *ssl;
SSL_CTX *ctx;
SSL_SESSION *session;
const char *dhfile;
const char *randfile;
#elif defined(WITH_GNUTLS) /* GNUTLS */
int (*fsslauth)(struct soap*);
void *fsslverify;
gnutls_certificate_credentials_t xcred; /* cert pointer */
gnutls_anon_client_credentials_t acred; /* anon pointer */
gnutls_priority_t cache; /* priority cache pointer */
gnutls_session_t session; /* session pointer */
gnutls_dh_params_t dh_params;
gnutls_rsa_params_t rsa_params;
#else /* No SSL/TLS */
void *fsslauth; /* dummy members, to preserve struct size */
void *fsslverify;
void *bio;
void *ssl;
void *ctx;
void *session;
void *dh_params;
void *rsa_params;
#endif
unsigned short ssl_flags;
const char *keyfile;
const char *password;
const char *cafile;
const char *capath;
const char *crlfile;
char session_host[SOAP_TAGLEN];
int session_port;
#ifdef WITH_C_LOCALE
locale_t c_locale; /* set to C locale by default */
#else
void *c_locale;
#endif
#ifdef WITH_ZLIB
z_stream *d_stream; /* decompression stream */
uLong z_crc; /* internal gzip crc */
#else
void *d_stream; /* dummy members, to preserve struct size */
soap_int32 z_crc;
#endif
const char *z_dict; /* support for zlib static dictionaries */
unsigned int z_dict_len;
short zlib_state; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_INFLATE */
short zlib_in; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */
short zlib_out; /* SOAP_ZLIB_NONE, SOAP_ZLIB_DEFLATE, or SOAP_ZLIB_GZIP */
char *z_buf; /* buffer */
size_t z_buflen;
unsigned short z_level; /* compression level to be used (0=none, 1=fast to 9=best) */
float z_ratio_in; /* detected compression ratio compressed_length/length of inbound message */
float z_ratio_out; /* detected compression ratio compressed_length/length of outbound message */
#ifdef WMW_RPM_IO /* VxWorks */
void *rpmreqid;
#endif
#ifdef __cplusplus
soap();
soap(soap_mode);
soap(soap_mode, soap_mode);
soap(const struct soap&);
virtual ~soap();
#else
void (*dummy)(void);
#endif
};

后来在图书馆中被广泛使用。我需要稍微修改一下行为,但即使是像

这样的简单行
struct soap *soap;
...
// soap->error is 401 up to this point
soap->error = 0;
// soap->error is still 401, at least according to VS2008 debugger

我做的第一件事是查看程序集:

soap->error = 0;
172A35D8 mov eax,dword ptr [soap]
172A35DB mov dword ptr [eax+191A4h],0

&soap->error = 0x0cb3ead0soap = 0x0cb25930,以及 0x0cb3ead0 - 0x0cb25930 = 0x191A0 少了 4 个字节。所以要么是调试器错了,要么是程序集错了,但是由于库可以正常工作,调试器上的疑虑很大。无论哪种方式,在这些情况下都不可能更改代码。

有什么建议可能导致这种情况吗?我的指针算法在某处有误吗?我试过了

#pragma pack(push)
#pragma pack(1)
...
#pragma pack(pop)

围绕结构定义,但这没有帮助。

最佳答案

四个字节的差异可能是由 C++ 编译器添加 vtable 引起的到结构的开头。要验证这种常量差异的存在,可以查看修改偏移量0处的元素时生成的代码(state)。

关于c++ - C++/gSoap 2.8.2 中奇怪的结构成员对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21384566/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com