흐르는 시간의 블로그...

원래는 CPPJSON 라이브러리를 쓰다가...

어차피 POCO의 Logger를 사용하는 중이기 때문에 하나라도 줄이자라는 생각에...

Poco::JSON을 사용하기로 하였다.


그러나... 간단한 문제가 어려운 상황에 봉착하였다.

영문으로는 아래에다 질문을 올렸고 잘 아는 어떤분(?)이 좋은 댓글을 달아 줬다.

나도 알아낸바가 있지만 짧은 영어로 길게 설명하기 어려워... 여기다가 좀 더 달아본다.


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


원래 소스코드는 저기가서 보시고...

수정한 소스코드는 아래에 있다.


stack overflow에서 지적된 부분의


첫번째는...

_object == NULL 로 비교하면 안된다는 부분이다.


두번째는

각 이름에 해당하는 부분들에 null 값이 올 수 있다는 점이다.

따라서 그 부분을 체크하지 않으면 exception이 발생한다.


세번째는

extract 대신 convert를 사용해야 한다는 점이다.

위의 링크에 가서 테스트에 사용한 bcodew값을 보면 서울 지역은 int 안쪽에 들어오고 다른 지역은 Int64를 사용해야 한다

"BCodeW"를 통해 가져온 값의 타입을 보면 Int 범위는 "i", Int64범위는 "l"을 보여준다.

extract는 해당하는 값의 레퍼런스를 가져오기 때문에 정확한 타입이 맞지 않으면 Bad Cast Exception을 발생시킨다.

Int64가 더 큰 범위임에서 자동 캐스팅이 발생하지 않는다.

큰 범위로 캐스팅해서 값을 가져오고자 한다면 convert를 사용하자.

// POCO JSON 사용
bool CUBIUtils::ParseAddressResult( llong& _BCodeW, char* _szPOI, char* _szJibun, char* _szAPIResult )
{
	JSON::Parser parser;
	try
	{
		formatlog( LOG_DEBUG, "CUBIUtils::%s(%d) AddrSrc: %s", __func__, __LINE__, _szAPIResult);

		JSON::Object::Ptr _object = parser.parse(_szAPIResult).extract();

		_BCodeW = 0;
		if ( _object->isNull("BCodeW"))
			formatlog( LOG_WARN, "CUBIUtils::%s(%d) BCodeW is NULL", __func__, __LINE__);
		else
			_BCodeW = _object->get("BCodeW").convert();

		if ( _object->isNull("poi"))
			formatlog( LOG_WARN, "CUBIUtils::%s(%d) poi is NULL", __func__, __LINE__);
		else
			strcpy( _szPOI, _object->get("poi").extract().c_str());

		if ( _object->isNull("jibun"))
			formatlog( LOG_WARN, "CUBIUtils::%s(%d) jibun is NULL", __func__, __LINE__);
		else
			strcpy( _szJibun, _object->get("jibun").extract().c_str());
	}
	catch(exception &e)
	{
		formatlog( LOG_ERROR, "CUBIUtils::%s(%d) JSON parsing Exception. %s", __func__, __LINE__, e.what());
		return false;
	}

	return true;
}