gsoap:stub代码(C++)在mingw下与C++11代码一起编译出错

32 篇文章 0 订阅
10 篇文章 0 订阅

理论上,gsoap生成的代码是可以在各种编译器下编译的。但现实是我用gsoap生成的c++代码,在windows/mingw就没办法编译,在windows/vs2015下可以正常编译,在linux/gcc也能 正常编译,给人的感觉似乎是没有在mingw下做过基本测试(真的是这样吗???)。

简单的错误

仔细研究了编译错误,其实都很简单,都是没有正确判断win32下的编译器类型。
例如下面这段代码(version 2.8.33的stdsoap2.cpp line 12973, soap_string_in函数)

#ifdef WIN32
          m = 0;
          wctomb_s(&m, buf, sizeof(buf), (wchar_t)(c & 0x7FFFFFFF));
#else
          m = wctomb(buf, (wchar_t)(c & 0x7FFFFFFF));
#endif

显然《wctomb》是标准c函数,而 带_s后缀的[《wctomb_s》] 2是msvc扩展的安全增强版本的函数。
只用#ifdef WIN32来判断,在msvc下编译是没问题,但用mingw编译时就报错了,因为mingw并没有实现wctomb_s

还好,gsoap的版本更新很快,当我更新到上个月(2016-08-17)发布的最新版本(2.8.34)时,发现上面这个问题被开发者修改了(version 2.8.33的stdsoap2.cpp line 12925, soap_string_in函数)

#if defined(WIN32) && !defined(CYGWIN) && !defined(__MINGW32__) && !defined(__MINGW64__)
            m = 0;
            wctomb_s(&m, buf, sizeof(buf), (wchar_t)(c & 0x7FFFFFFF));
#else
            m = wctomb(buf, (wchar_t)(c & 0x7FFFFFFF));
#endif

虽然修改的不那么漂亮,但总算是改了。

简单的修改

但当我用新版本重新运行wsdl2h,soapcpp2 生成了c++代码,再次尝试mingw下编译时,又报错了,还是类似的问题。
这次问题出在stdsoap2.h(version 2.8.34 line 1299,2.8.34以前的版本都一样)

#ifdef WIN32 
# ifndef HAVE_ISNAN
#  define HAVE_ISNAN
# endif
# define soap_isnan(n) _isnan(n)
# ifndef HAVE_ISINF
#  define HAVE_ISINF
# endif
# define soap_isinf(n) (!_finite(n))
#endif

于是我也依样画葫芦将这段代码修改如下,则编译通过

#if defined(WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
# ifndef HAVE_ISNAN
#  define HAVE_ISNAN
# endif
# define soap_isnan(n) _isnan(n)
# ifndef HAVE_ISINF
#  define HAVE_ISINF
# endif
# define soap_isinf(n) (!_finite(n))
#endif

事情就这样结束了么?

我总觉得gsoap不会对这么明显而且简单的问题在之前的那么多版本都解决不了,对于本文一开始我的推断:gsoap没有在mingw下做过基本测试,我总是有点心虚的。
联想到我的系统代码都用c++11标准写的所以我的项目cmake脚本(CMakeLists.txt)中默认对整个项目都增加了-std=c++11选项。

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
	set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
	message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)

也就是说stdsoap2.cpp实际是在-std=c++11选项下编译的。
会不会是因为这个-std=c++11选项引起的问题呢?
于是我尝试删除-std=c++11选项,恢复前面的所有修改,再编译,则编译通过。

现在问题搞明白了,上面的实验推翻我前面的一系列结论:

gsoap生成的c++代码在c++98标准下编译应该是没问题的,
但gsoap的开发者并没有用-std=c++11选项在mingw下编译测试过,所以会有前面那些问题。

所以解决在gsoap stub代码和C++11代码一起在mingw下编译的问题有两个方案:
方案1.修改自己CMakeLists.txt,将gsoap生成的C++代码与自己的项目c++11代码区分开,不用-std=c++11选项编译gsoap代码,这样就可以避免修改gsoap代码(stdsoap2.h/stdsoap2.cpp)。
方案2.与方案1相反,就像前面的办法一样修改stdsoap2.h/stdsoap2.cpp以解决编译问题.这样可以不用修改自己的CMakeLists.txt,将gsoap生成的c++代码与自己的C++11代码混在一起编译。

选项哪个方案都可以取决哪个方案成本最低,
但我准备选择项方案1—原因是不到万不得已我不会修改第三方代码,这样会增加未来的维护成本 。
不过以现在gsoap每月发布一个版本的更新速度,下一个版本应该就能完美解决mingw下对-std=c++11选项的支持问题了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值