-3

I am trying to pass some variadic parameters, but I am having no success.

Code:

void Dispositivo::enviarComandoPTZ( AcaoPTZEnum in_acao, DirecaoPTZEnum in_direcao )
{
    std::string direcao = direcaoPTZMap[in_direcao];
    std::string acao = StringUtil::to_string(in_acao);

    char* buf = ByteUtil::hexStringToRawBytes( ComandoUtil::gerarComando( PTZ, m_sessao, acao.c_str(), direcao.c_str(), "4") ); // IT CRASHES HERE

    int len = sizeof(buf);
    m_pSocket->Write( buf, len );
}

std::string ComandoUtil::gerarComando(TipoComandoEnum in_tipo, std::string in_sessao, ...)
{
    va_list parametros;
    va_start ( parametros, in_sessao );

    std::string payload = obterPayload(in_tipo,parametros);

    Requisicao requisicao = Requisicao(in_tipo, payload, in_sessao);

    return requisicao.gerarDados();
}

std::string ComandoUtil::obterPayload( TipoComandoEnum tipo, va_list parametros)
{
    return (wxString::FormatV(_(payloadMap[tipo]),parametros)).ToStdString();
}

payloadMap is a map which holds the strings I need to format.

I am gettin a segmentation fault at the 3rd line of enviarComandoPTZ();

RafaelTSCS
  • 1,234
  • 2
  • 15
  • 36
  • Did you try debugging and seeing what crashes? It might be the `my_fucntion` code that is the problem. – crashmstr Jul 01 '14 at 12:30
  • Does your omitted code try to access anything more / other than three C-strings as the optional argumants? No repro because you didn't provide an [MCVE](http://stackoverflow.com/help/mcve). – Deduplicator Jul 01 '14 at 12:32
  • Here is the answer: http://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c – lextiz Jul 01 '14 at 12:33
  • It crashes while trying to call my_function, it doesn't even get to the ommited code. It is like it is not accepting the parameters. I get no other error message beside the segmentation fault. – RafaelTSCS Jul 01 '14 at 12:43
  • How are you telling the function which variadic types to expect? Are you sure you're accessing the correct number as the correct type (3 of `const char*` in you example)? – Mike Seymour Jul 01 '14 at 12:43
  • I just pass these parameters to a wxString::FormatV() – RafaelTSCS Jul 01 '14 at 12:50
  • 2
    "What am I doing wrong?" - you're not posting a complete test case. Your code runs with no segmentation fault if I add enough missing code to compile and run it: http://ideone.com/fe1v93. – Mike Seymour Jul 01 '14 at 12:51
  • 1
    Exactly how do you pass them to that function? Does `some_str` contain the correct format specifiers to match the variadic arguments? Does your real function return a value (your posted code doesn't, which is likely to cause a crash)? – Mike Seymour Jul 01 '14 at 12:55
  • I ahve just edited the code so you guys can see exactly what i am doing – RafaelTSCS Jul 01 '14 at 13:04
  • 1
    `obterPayload` does not expect a `va_list`. No wonder you have trouble. – Deduplicator Jul 01 '14 at 13:06
  • I am new to C++, I thought the dots would represent a va_list. But it makes sense. I did this change, but it still doesn't work. It crashes before the call to obterPayload. – RafaelTSCS Jul 01 '14 at 13:10

2 Answers2

0

Look at this. Maybe your string is greater then 1024 symbols ?

It could be because of ToStdString: your implementation of std::string is not equal to wxWidget's one. Try to call:

return (wxString::FormatV(_(payloadMap[tipo]),parametros)).c_str();

Break this call to steps like this

wxString str = payloadMap[ tipo ];
wxString fmt = _( str ); // BTW, what is this ?
wxString res = wxString::FormatV( fmt, parametros );
return res.c_str();

and run it with debugger

borisbn
  • 4,988
  • 25
  • 42
  • Thanks for your reply, @borisbn. But if I try to call as you suggested it doesn't compile. wxString::FormatV already returns const *char. I did these changes, but it still crashes on the same call. – RafaelTSCS Jul 01 '14 at 13:26
  • First: "wxString::FormatV already returns const *char" It can't return `char*` because you can't call `ToStdString` from pointer... only from wxString's object. Second: what is `_` ? Third: look at edit I did to answer – borisbn Jul 01 '14 at 13:37
  • I meant const char*, sorry. _() is an initializer for wxString. It converts from literal to wxString. [look here](http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString). I am making some modifications and will post the results. – RafaelTSCS Jul 01 '14 at 13:46
  • No success :(. It keeps crashing at the call to ComandoUtil::gerarComando(); – RafaelTSCS Jul 01 '14 at 13:58
  • I was checking the parameters I am trying to pass, and I noticed that the segmentation fault is coming from the m_sessao. This a protected attribute from the class Dispositivo. Idk why this is happening since this method is also in Dispositivo. – RafaelTSCS Jul 01 '14 at 15:56
  • I've got it. The object (Dispositivo) I was trying to use was null. I am not really a C++ developer, I'm used to Java, so I was expecting the nullpointer to happen before, at the moment I tried to call the function. But it only happens when I try to access the attribute. Thank you for your patience! – RafaelTSCS Jul 02 '14 at 11:03
  • btw, I changed the string formating to: vsnprintf(&buf[0], buf.size(),payload.c_str(), parametros) < 0 ... performing a check for the buffer size, fo safety. Was getting no luck withthe wxString::FormatV – RafaelTSCS Jul 02 '14 at 12:57
0

The problem was not really related to the variadic parameters. One of the function parameters (m_sessao) was not accessible because the object Dispositivo was null.

It took me a while to notice this because as I am used to Java, I was expecting any "nullpointerexception" to happen if I tried to access a function of a null object too, and not only after trying to access the attribute; as soon as the function I was calling was into "Dispositivo" and it is not static, I assumed it was not null.

Thank you for those who tried to help. I got some good tips to fix the code.

RafaelTSCS
  • 1,234
  • 2
  • 15
  • 36