I hope someone can help me get jsonrpc-cpp to compile. (http://jsonrpc-cpp.sourceforge.net/)
When I type scons
as per the documentation, I get:
eamorr@Compaq6000:~/Desktop/jsonrpc-cpp$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o src/jsonrpc_handler.os -c -std=c++98 -Wall -Wextra -pedantic -Wredundant-decls -Wshadow -Werror -O2 -fPIC src/jsonrpc_handler.cpp
src/jsonrpc_handler.cpp: In member function ‘bool Json::Rpc::Handler::Process(const std::string&, Json::Value&)’:
src/jsonrpc_handler.cpp:208:25: error: ambiguous overload for ‘operator[]’ in ‘root[i]’
/usr/local/include/json/value.h:322:14: note: candidates are: Json::Value& Json::Value::operator[](Json::Value::ArrayIndex)
/usr/local/include/json/value.h:329:14: note: Json::Value& Json::Value::operator[](int)
/usr/local/include/json/value.h:334:20: note: const Json::Value& Json::Value::operator[](Json::Value::ArrayIndex) const
/usr/local/include/json/value.h:339:20: note: const Json::Value& Json::Value::operator[](int) const
src/jsonrpc_handler.cpp:213:23: error: ambiguous overload for ‘operator[]’ in ‘response[j]’
/usr/local/include/json/value.h:322:14: note: candidates are: Json::Value& Json::Value::operator[](Json::Value::ArrayIndex)
/usr/local/include/json/value.h:329:14: note: Json::Value& Json::Value::operator[](int)
/usr/local/include/json/value.h:334:20: note: const Json::Value& Json::Value::operator[](Json::Value::ArrayIndex) const
/usr/local/include/json/value.h:339:20: note: const Json::Value& Json::Value::operator[](int) const
scons: *** [src/jsonrpc_handler.os] Error 1
scons: building terminated because of errors.
Here is src/jsonrpc_handler.cpp
(I've marked lines 208 and 213):
/*
* JsonRpc-Cpp - JSON-RPC implementation.
* Copyright (C) 2008-2011 Sebastien Vincent <sebastien.vincent@cppextrem.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file jsonrpc_handler.cpp
* \brief JSON-RPC server processor engine.
* \author Sebastien Vincent
*/
#include "jsonrpc_handler.h"
namespace Json
{
namespace Rpc
{
CallbackMethod::~CallbackMethod()
{
}
Handler::Handler()
{
/* add a RPC method that list the actual RPC methods contained in the Handler */
Json::Value root;
root["description"] = "List the RPC methods available";
root["parameters"] = Json::Value::null;
root["returns"] = "Object that contains description of all methods registered";
AddMethod(new RpcMethod<Handler>(*this, &Handler::SystemDescribe, std::string("system.describe"), root));
}
Handler::~Handler()
{
/* delete all objects from the list */
for(std::list<CallbackMethod*>::const_iterator it = m_methods.begin() ; it != m_methods.end() ; it++)
{
delete (*it);
}
m_methods.clear();
}
void Handler::AddMethod(CallbackMethod* method)
{
m_methods.push_back(method);
}
void Handler::DeleteMethod(const std::string& name)
{
/* do not delete system defined method */
if(name == "system.describe")
{
return;
}
for(std::list<CallbackMethod*>::iterator it = m_methods.begin() ; it != m_methods.end() ; it++)
{
if((*it)->GetName() == name)
{
delete (*it);
m_methods.erase(it);
break;
}
}
}
bool Handler::SystemDescribe(const Json::Value& msg, Json::Value& response)
{
Json::Value methods;
response["jsonrpc"] = "2.0";
response["id"] = msg["id"];
for(std::list<CallbackMethod*>::iterator it = m_methods.begin() ; it != m_methods.end() ; it++)
{
methods[(*it)->GetName()] = (*it)->GetDescription();
}
response["result"] = methods;
return true;
}
std::string Handler::GetString(Json::Value value)
{
return m_writer.write(value);
}
bool Handler::Check(const Json::Value& root, Json::Value& error)
{
Json::Value err;
/* check the JSON-RPC version => 2.0 */
if(!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0")
{
error["id"] = Json::Value::null;
error["jsonrpc"] = "2.0";
err["code"] = INVALID_REQUEST;
err["message"] = "Invalid JSON-RPC request.";
error["error"] = err;
return false;
}
if(root.isMember("id") && (root["id"].isArray() || root["id"].isObject()))
{
error["id"] = Json::Value::null;
error["jsonrpc"] = "2.0";
err["code"] = INVALID_REQUEST;
err["message"] = "Invalid JSON-RPC request.";
error["error"] = err;
return false;
}
/* extract "method" attribute */
if(!root.isMember("method") || !root["method"].isString())
{
error["id"] = Json::Value::null;
error["jsonrpc"] = "2.0";
err["code"] = INVALID_REQUEST;
err["message"] = "Invalid JSON-RPC request.";
error["error"] = err;
return false;
}
return true;
}
bool Handler::Process(const Json::Value& root, Json::Value& response)
{
Json::Value error;
std::string method;
if(!Check(root, error))
{
response = error;
return false;
}
method = root["method"].asString();
if(method != "")
{
CallbackMethod* rpc = Lookup(method);
if(rpc)
{
return rpc->Call(root, response);
开发者_Go百科}
}
/* forge an error response */
response["id"] = root.isMember("id") ? root["id"] : Json::Value::null;
response["jsonrpc"] = "2.0";
error["code"] = METHOD_NOT_FOUND;
error["message"] = "Method not found.";
response["error"] = error;
return false;
}
bool Handler::Process(const std::string& msg, Json::Value& response)
{
Json::Value root;
Json::Value error;
bool parsing = false;
/* parsing */
parsing = m_reader.parse(msg, root);
if(!parsing)
{
/* request or batched call is not in JSON format */
response["id"] = Json::Value::null;
response["jsonrpc"] = "2.0";
error["code"] = PARSING_ERROR;
error["message"] = "Parse error.";
response["error"] = error;
return false;
}
if(root.isArray())
{
/* batched call */
size_t i = 0;
size_t j = 0;
for(i = 0 ; i < root.size() ; i++)
{
Json::Value ret;
Process(root[i], ret); //line 208!
if(ret != Json::Value::null)
{
/* it is not a notification, add to array of responses */
response[j] = ret; //line 213!
j++;
}
}
return true;
}
else
{
return Process(root, response);
}
}
bool Handler::Process(const char* msg, Json::Value& response)
{
std::string str(msg);
return Process(str, response);
}
CallbackMethod* Handler::Lookup(const std::string& name) const
{
for(std::list<CallbackMethod*>::const_iterator it = m_methods.begin() ; it != m_methods.end() ; it++)
{
if((*it)->GetName() == name)
{
return (*it);
}
}
return 0;
}
} /* namespace Rpc */
} /* namespace Json */
I'm really hoping someone might be able to point me in the right direction.
Many thanks in advance,
Edit: Here's what I did on lines 208 and 213:
Process(root[(Json::Value::ArrayIndex)i], ret); //line 208
response[(Json::Value::ArrayIndex)j] = ret; //line 213
As the operator[]
expects either int
or Json::Value::ArrayIndex
, you should pass one of those instead of a size_t
. I guess that ArrayIndex
is a signed type, too, or sizeof(size_t)>sizeof(ArrayIndex)
, so there is no good conversion of size_t
to either int
or ArrayIndex
, therefore it is ambiguous.
Maybe post a suggestion to the developers or find out about the motivation for not using the more idiomatic size_t
.
On line 208
Process(root[i], ret); //line 208!
the compiler says that i
can be either int
or Json::Value::ArrayIndex
(but it is size_t).
From what I can find about Json, the index could be
typedef unsigned int ArrayIndex;
And on your machine size_t
obviously doesn't match that. Perhaps it is unsigned long
or unsigned long long
?
In that case I think it can be time for a bug report about missing portability.
精彩评论