当我尝试转换 Int64 时,poco-library 出现错误的转换异常

Bad cast exception on poco-library when I tried to cast Int64

我写了一些代码来解析 JSON 字符串。 有时我得到 "Bad Cast Exception"。 在我的 JSON 字符串中 1。 2. 不引发异常和 3。 4. 引发异常。

两组的区别在于1。 2.的BCodeW在长范围内,3。 4.的BCodeW在Int64范围内。

为什么转换会引发异常?

我为 Bad Cast Exception 写了一些保护代码,但我想知道异常的原因。

感谢阅读。


我的环境如下。


下面是我的 JSON 字符串示例。

  1. {"y":37.56376,"x":126.97287,"poiY":37.563686111111,"poiX":126.97302222222,"jibunY":37.563805555556,"jibunX":126.97285833333,"BCodeW":1114016700,"poi":"...","jibun":"..."}
  2. {"y":37.59771,"x":127.041493,"poiY":37.597605555556,"poiX":127.041725,"jibunY":37.597547222222,"jibunX":127.04176666667,"BCodeW":1129013600,"poi":"...","jibun":"..."}
  3. {"y":36.760035,"x":127.250362,"poiY":36.759905555556,"poiX":127.25036111111,"jibunY":36.760119444444,"jibunX":127.25040833333,"BCodeW":4413125029,"poi":"...","jibun":"..."}
  4. {"y":36.129513,"x":128.34381,"poiY":36.128672222222,"poiX":128.34373888889,"jibunY":36.129738888889,"jibunX":128.34425833333,"BCodeW":4719010200,"poi":"...","jibun":"..."}

我的代码在下面。

bool CUBIUtils::ParseAddressResult( llong& _BCodeW, char* _szPOI, char* _szJibun, char* _szAPIResult )
{
  JSON::Parser parser;
  try
  {
    JSON::Object::Ptr _object = parser.parse(_szAPIResult).extract<JSON::Object::Ptr>();
    if ( NULL == _object)
    {
      formatlog( LOG_ERROR, "JSON parsing failed");
      return false;
    }

    formatlog( LOG_DEBUG, "CUBIUtils::%s(%d) AddrSrc: %s", __func__, __LINE__, _szAPIResult);

    _BCodeW = 0;
    try
    {
      _BCodeW = _object->get("BCodeW").extract<Int64>();
    }
    catch(exception &_e)
    {
      _BCodeW = _object->get("BCodeW").extract<int>();
    }

    strcpy(   _szPOI, _object->get("poi").extract<std::string>().c_str());
    strcpy( _szJibun, _object->get("jibun").extract<std::string>().c_str());
  }
  catch(exception &e)
  {
    formatlog( LOG_ERROR, "CUBIUtils::%s(%d) JSON parsing Exception. %s", __func__, __LINE__, e.what());
    return false;
  }

  return true;
}

Var.h 在 Poco 的源代码中说。

  /// Invoke this method to perform a safe conversion.
  ///
  /// Example usage:
  ///     Var any("42");
  ///     int i = any.convert<int>();
  ///
  /// Throws a RangeException if the value does not fit
  /// into the result variable.
  /// Throws a NotImplementedException if conversion is
  /// not available for the given type.
  /// Throws InvalidAccessException if Var is empty.

下面的代码有效。

使用convert<T>()代替extract<T>()

数据类型不同。 "i", "l"

extract获取完全匹配类型的数据。

_BCodeW = 0;
if ( _object->isNull("BCodeW"))
  cout << "BCodeW is NULL" << endl;
else
{
  Dynamic::Var _BCodeWVar = _object->get("BCodeW");
  cout << "Data Type is " << _BCodeWVar.type().name() << endl;

  _BCodeW = _BCodeWVar.convert<Int64>();
  cout << "BCodeW is " << _BCodeW << endl;
}

这里的问题不在JSON解析and/or数据提取。它在比较行中:

if (NULL == _object)

该行将导致抛出 BadCastException。

原因是因为 operator== 解析为

inline bool operator == (const Poco::Int32& other, const Var& da)

Poco::JSON::Object::PtrPoco::Int32conversion 抛出。

将有问题的行替换为

if (_object.isNull())

一切都会好起来的。