如果用soap调用web service 或者 wcf,如果传输的参数,没有用到unicode,则没有事情,一切都OK的,
但是,如果传输的参数中,如果有包含unicode的,则无论上传或者下载,都有问题.
解决方案如下:
路径:C:\gsoap_2.8.7\gsoap-2.8\gsoap\bin\win32
1:用wsdl2h -s -o test.h 来生成头文件; (生成的是C++头文件)
参考 : http://blog.csdn.net/gogor/article/details/5896135
2:用soapcpp2 test.h来生成相关C++信息(这里生成所有的)
在这里,我们只用4个文件:soapC.cpp、soapClient.cpp、soapH.h、soapStub.h,
以及gsoap自带的stdsoap2.cpp、stdsoap2.h,总共6个文件,将这6个文件拷贝到工程里.
【不要用代理类,因为代理类设置字符的时候,会出错。】
3:写代码:
(1)
struct soap soap1 ;
_ns3__GetChar ns3 ;
_ns3__GetCharResponse ns3Response ;
soap_init(&soap1);
soap_set_mode(&soap1, SOAP_C_MBSTRING);
int nOK = soap_call___ns1__GetChar(&soap1,szUrl,NULL,&ns3,&ns3Response);
如上,需要设置字符的传输模式,由于_ns3__GetChar 类里面变量类型是char*的,所以在转换的时候,需要进行设置,否则会*s++ = (char)(c & 0xFF);
即高位被屏蔽掉.
(2)
还需要对stdsoap2.cpp配置地域化信息,否则刚才设置的系统读取不到的,修改位置在soap_string_in最后一个HAVE_WCTOMB
#ifdef HAVE_WCTOMB
if (soap->mode & SOAP_C_MBSTRING)
{
(void)setlocale(LC_ALL,"");
m = wctomb(buf, (wchar_t)(c & 0x7FFFFFFF));
int nMB_CUR_MAX = (int)MB_CUR_MAX ;
if (m >= 1 && m <= nMB_CUR_MAX)
{ t = buf;
*s++ = *t++;
m--;
}
else
{ *s++ = SOAP_UNKNOWN_CHAR;
m = 0;
}
}
else
#endif
同理,soap_string_out也要进行配置地域化信息,
#ifdef HAVE_MBTOWC
if (soap->mode & SOAP_C_MBSTRING)
{ wchar_t wc;
(void)setlocale(LC_ALL,"");
register int m = mbtowc(&wc, t - 1, MB_CUR_MAX);
if (m > 0 && !((soap_wchar)wc == c && m == 1 && c < 0x80))
{ if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
return soap->error;
s = t += m - 1;
continue;
}
}
#endif
到这里,问题已经解决了,其它修改的地方,一个是命名空间修改,还有修改3个.cpp不进行预编译头文件,
奶奶的,折腾我N久了,终于被狗屁好了!
还有一个,如果要开启调试模式,则在stdsoap2.h里有一个宏 define DEBUG,搜索下就知道了!默认是关闭调试信息的
补充说明,如果WCF有用到结构体或者类,我这边生成出来的相应结构体或者类,其成员都是指针类型的话,
WCF方要把我这边指针所对应的的变量都赋值,否则我这里去调用函数的时候会报错,说类型不匹配,因为如果返回是空指针的话,
如果我这里误调用了空指针,程序就会崩溃的,哈哈C++够严谨吧!