Accessing a protocol buffer extension repeated field from C++ - c++

In the following protocol buffer, how does one access the repeated fields in the extension from C++?
base.proto
message Base {
optional int32 id = 1;
repeated int32 ids = 2;
optional string name = 3;
repeated string names = 4;
extensions 1000 to 1999;
}
ext.proto
import "base.proto";
extend Base {
repeated string names = 1000;
optional int32 number = 1001;
repeated int32 numbers = 1002;
optional string name = 1003;
}
The following doesn't compile (in VS2010)
#include "base.pb.h"
#include "ext.pb.h"
using namespace ::google::protobuf;
int main(int argc, char *argv[])
{
Base b;
RepeatedPtrField<std::string> base_names = b.names(); // OK
RepeatedField<int> base_ids = b.ids(); // OK
int ext_number = b.GetExtension(number); // OK
std::string ext_name = b.GetExtension(name); // OK
assert( b.HasExtension(numbers) ); // OK
assert( b.HasExtension(names) ); // OK
int32 i = b.GetExtension(numbers); // ? Compiles but doesn't make sense.
RepeatedField<int32> ext_numbers = b.GetExtension(numbers); // compilation fails:
RepeatedPtrField<std::string> ext_names = b.GetExtension(names); // compilation fails:
return 0;
}
Compilation errors
1>test_proto.cpp(17): error C2440: 'initializing' : cannot convert from 'int' to 'google::protobuf::RepeatedField<Element>'
1> with
1> [
1> Element=google::protobuf::int32
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1>\test_proto.cpp(18): error C2440: 'initializing' : cannot convert from 'const std::string' to 'google::protobuf::RepeatedPtrField<Element>'
1> with
1> [
1> Element=std::string
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous

Thanks to Feng Xiao on the protobuf mailing list, use ExtensionSize(id) and GetExtension(id, index):
Base b;
int index = 0;
if (index < b.ExtensionSize(names))
{
std::string s_value = b.GetExtension(names, index);
}

Related

C++ getting error C2440

Hello I'm using Visual Studio c++ 2010
I'm having a problem with this code ( it's taken from C language code ) :
MEMBLOCK* create_memblock (HANDLE hProc, MEMORY_BASIC_INFORMATION *meminfo)
{
MEMBLOCK *mb = malloc(sizeof(MEMBLOCK));
if (mb)
{
mb->hProc = hProc;
mb->addr = meminfo->BaseAddress;
mb->size = meminfo->RegionSize;
mb->buffer = malloc(meminfo->RegionSize);
mb->next = NULL;
}
return mb;
}
I'm having these errors :
error C2440: 'initializing' : cannot convert from 'void *' to 'MEMBLOCK *'
error C2440: '=' : cannot convert from 'PVOID' to 'unsigned char *'
error C2440: '=' : cannot convert from 'void *' to 'unsigned char *'
I'm kinda newbie. Can you please provide a converted code for this that actually works with c++.
Thank you
Since you're programming in C++, you should not use the old C function malloc. Instead I would recommend that you use the C++ new construct:
MEMBLOCK *mb = new MEMBLOCK;
In C++ You may not assign a pointer of type void * to a pointer of some other type. So for example instead of writing
MEMBLOCK *mb = malloc(sizeof(MEMBLOCK));
You have to write
MEMBLOCK *mb = ( MEMBLOCK * )malloc(sizeof(MEMBLOCK));
Also you have to change other statements where there is the same problem. It seems these statements are
mb->addr = ( unsigned char * )meminfo->BaseAddress;
mb->buffer = ( unsigned char * )malloc(meminfo->RegionSize);
It is a good example of that you always should use an explicit casting even in C. That makes the code more safe and clear.
malloc() returns void*, and C++ does not automatically cast void* to a different pointer type. So you have to cast the return value:
MEMBLOCK *mb = (MEMBLOCK*) malloc(sizeof(MEMBLOCK));
Try:
MEMBLOCK* create_memblock (HANDLE hProc, MEMORY_BASIC_INFORMATION *meminfo)
{
MEMBLOCK *mb = (MEMBLOCK*)malloc(sizeof(MEMBLOCK));
if (mb)
{
mb->hProc = hProc;
mb->addr = meminfo->BaseAddress;
mb->size = meminfo->RegionSize;
mb->buffer = malloc(meminfo->RegionSize);
mb->next = NULL;
}
return mb;
}

Resolve c++ pointer-to-member error in VS 2003

I have a c++ program that I'm trying to port from VS98 to VS2003 (incremental steps). One error that occurs throughout is "Error 2275"
For instance: k:\RR\chart\chartdlg.cpp(2025): error C2475: 'CRrDoc::cFldFilter' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name
The offending code is shown below:
void CDataPage::OnBtnLabelField()
{
FLDID fid ;
LPMFFIELD f ;
CRrApp *pApp = (CRrApp *)AfxGetApp();
CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd();
CRrDoc *pDoc = (CRrDoc *)pFrame->GetActiveDocument();
CSelectFieldDlg dlg;
//**************************************************
//BOOL CRrDoc::*zcFldFilter = &CRrDoc::cFldFilter;
//dlg.ck = CRrDoc->*zcFldFilter;
//**************************************************
dlg.ck = pDoc->cFldFilter ;
dlg.TitleTextID = IDS_2676;
fid = (FLDID)dlg.DoModal();
if (fid != NOID)
{
f = pDoc->m_pComposite->mfbyndx(fid);
// find index
int i, iCount;
iCount = m_lboxLabel.GetCount();
for (i = 0; i < iCount; i++)
{
if(fid == m_lboxLabel.GetItemData(i))
{
m_lboxLabel.SetCurSel(i);
OnSelchangeComboLabel();
}
}
}
}
I tried handling it according to a Microsoft page: But that just generated a set of other problems (the commented code between the asterisks). Note that I also commented out the following line:
dlg.ck = pDoc->cFldFilter
Unfortunately, this leads to a new error: k:\RR\chart\chartdlg.cpp(2022): error C2440: 'initializing' : cannot convert from 'BOOL (__cdecl )(LPMFFIELD)' to 'BOOL CRrDoc:: '
The definition in the .H file looks like:
public:
static BOOL cFldFilter(LPMFFIELD f);
Any ideas how to handle the pointer-to-member issue?
since you have:
static BOOL CRrDoc::cFldFilter(LPMFFIELD f);
its type is not a member variable but a function:
//BOOL CRrDoc::*zcFldFilter = &CRrDoc::cFldFilter; // doesn't work
BOOL (*zcFldFilter)(LPMFFIELD) = &CRrDoc::cFldFilter; // works
Since dlg.ck is of a correct type, you should do
dlg.ck = &CRrDoc::cFldFilter;

error C2663: overloads have no legal conversion for 'this' pointer

please help me for this errors
code:
u16 ip_defragment(){
u16 result;
fragip_set::iterator i;
IP_FRAGMENTED new_defrag;
IP* pcurpack = (IP*) malloc(cur.len);
memcpy(pcurpack, cur.data, cur.len);
new_defrag.saddr = cur.saddr;
new_defrag.daddr = cur.daddr;
new_defrag.protocol = cur.ip.ppack->protocol;
new_defrag.id = i2i(cur.ip.ppack->id);
i = ip_frags.find(new_defrag);
if(i != ip_frags.end()){
i->packets.insert(pcurpack);
const_cast<u16&>(i->cur_len) += cur.ip.len - cur.ip.hlen;
const_cast<u32&>(i->last_time) = time();
if(!(cur.ip.bmore_fr) && (i->tot_len == 0)){
const_cast<u16&>(i->tot_len) = cur.ip.fr_offs + cur.ip.len;
}
if(i->cur_len == i->tot_len){
for(set<IP*>::iterator k = i->packets.begin(); k != i->packets.end(); k++){
// must copy to another buffer
if(i2i((*k)->frag_off) & IP_OFFMASK){
memcpy(ip_defrag_buffer, *k, (*k)->ihl<<2);
} else {
memcpy(ip_defrag_buffer + (i2i((*k)->frag_off) & IP_OFFMASK) * 8,
*k + ((*k)->ihl<<2), (i2i((*k)->tot_len))-((*k)->ihl<<2));
}
}
IP* defr_ip = (IP*) &ip_defrag_buffer;
defr_ip->tot_len = i2i(i->tot_len);
defr_ip->frag_off = 0;
result = i->tot_len;
ip_frags.erase(i);
return result;
}
return 0;
}
if(!(cur.ip.bmore_fr)){
new_defrag.tot_len = cur.ip.fr_offs + cur.len;
} else {
new_defrag.tot_len = 0;
}
new_defrag.cur_len = cur.ip.len; // with header size
new_defrag.last_time = time();
i = ip_frags.insert(new_defrag).first;
if(i != ip_frags.end())
i->packets.insert(pcurpack);
return 0;
}
compiled project and view only 2 errors similar
line 15 : i->packets.insert(pcurpack);
end line : i->packets.insert(pcurpack);
error with 2 lines : error C2663: 'std::_Tree<_Traits>::insert' : 4 overloads have no legal conversion for 'this' pointer
IntelliSense: no instance of overloaded function "std::set<_Kty, _Pr, _Alloc>::insert [with _Kty=IP *, _Pr=std::less<IP *>, _Alloc=std::allocator<IP *>]" matches the argument list and object (the object has type qualifiers that prevent a match)
please help me?
I had exact same error with std::set, while passing it to a lambda expression:
C2663 'std::_Tree<std::_Tset_traits<_Kty,_Pr,_Alloc,false>>::insert': 5 overloads have no legal conversion for 'this' pointer
lambda expression prototype was:
[se1, ele1](auto val) {
/* here I was editing se1 set, but above se1 is passed value type */
}
I have changed to:
[&se1, ele1](auto val) {
/* now since se1 set is sent as reference type above, it is good to edit
changes stays as I expect it to be
*/
}
Now compilation succeeds.
I used with count_if function, which calls the lamda expression for eac element, so the compiler knows that modifications should persist in set se1, which is perfectly logical.
If you desire to have the original set unchanged, then send a copy of it.

Getting a mysterious type conversion when using the get function from Maya API class MArgList

I am using the MArgList class from the Maya API to retrieve arguments entered in the Maya command line. According to the class reference MArgList::get should be able to take an int or double as its second argument but it seems to be expecting a bool only and so throws a conversion error during compiling. The following is the code section and the errors generated. Any thoughts on what might be causing this would be much appreciated. The code was typed straight out of a tutorial on Maya plugin development, so it is a mystery why it is not working.
const int nPosts = 5;
const double radius = 0.5;
const double height = 5.0;
unsigned index;
index = args.flagIndex( "n", "number" );
if( MArgList::kInvalidArgIndex != index )
args.get( index + 1, nPosts );
unsigned index;
index = args.flagIndex( "r", "radius" );
if( MArgList::kInvalidArgIndex != index )
args.get( index + 1, radius );
unsigned index;
index = args.flagIndex( "h", "height" );
if( MArgList::kInvalidArgIndex != index )
args.get( index + 1, height );
1>Posts1Cmd.cpp(37): error C2664: 'MStatus MArgList::get(unsigned int,bool &) const' : cannot convert parameter 2 from 'const int' to 'bool &'
1>Posts1Cmd.cpp(39): error C2086: 'unsigned int index' : redefinition
1> Posts1Cmd.cpp(34) : see declaration of 'index'
1>Posts1Cmd.cpp(42): error C2664: 'MStatus MArgList::get(unsigned int,bool &) const' : cannot convert parameter 2 from 'const double' to 'bool &'
1>Posts1Cmd.cpp(44): error C2086: 'unsigned int index' : redefinition
1> Posts1Cmd.cpp(34) : see declaration of 'index'
1>Posts1Cmd.cpp(47): error C2664: 'MStatus MArgList::get(unsigned int,bool &) const' : cannot convert parameter 2 from 'const double' to 'bool &'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
If you are going to get new values from the get function, you cannot have the target variables const.
Try
int nPosts = 5;
double radius = 0.5;
double height = 5.0;
Also, you should not declare a new index variable for each call. Just declare it once and reuse it.

v8 setting Handle<Value> array howto?

I want to set a Handle<Value> of an array. I'm a beginner to v8 and i can't found how to set it
when I do for example:
Persistent<Context> fcontext
Handle<Value> Arr = Array::New(0);
Persistent<Function> Func;
Handle<Value> result = Func->Call(fcontext->Global(), 0, Arr);
I receive this error:
error C2664: 'v8::Function::Call' : cannot convert parameter 3 from 'v8::Handle<T>' to 'v8::Handle<T> []'
1> with
1> [
1> T=v8::Value
1> ]
How do I make a Handle<Value> of an array with 1 element ?
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(String::New("Hello World!")) };
func->Call(Context::GetCurrent()->Global(), argc, argv);
More examples:
http://izs.me/v8-docs/examples.html
http://nodejs.org/api/addons.html