Ir ao conteúdo
  • Cadastre-se
Entre para seguir isso  
Isabeleaa

[Resolvido] Chamada de função traduzida para OO não funciona

Recommended Posts

Olá pessoal,

Estou "traduzindo" um código sequencial para orientado a objetos e logo na primeira chamada de função não funcionou. Estou usando o Sublime no Ubuntu.

O programa cpp sequencial compila e funciona normalmente, usando uma biblioteca (sensor.h) )proprietária fornecida pelo fabricante de um sensor que estou usando.

Executo via terminal passando a localização do sensor na chamada:

./programa /dev/usb/hiddev0

Resumindo, é algo assim:


...
#include "sensor"

char *portaA = NULL; //ponteiro para a localização do sensor
tipoSensor *sensorA = NULL; //ponteiro para o sensor


main (int argc, char** arv[]) {
...
if (argc=2) {

portaA=argv[1];

//protótipo da função de sensor.h é: tipoSensor *fdOpen(char *porta)
sensorA=fdOpen(portaA);

leSensor();
fechaSensor();
}
...
}

Para organizar o código e deixá-lo reaproveitável, quero fazer o programa orientado a objeto. Estou enferrujada na teoria de OO, andei lendo pra relembrar, mas nunca tinha usado em C++.

Criei um arquivo LeSensor.h, com os protótipos das classes e métodos, e variáveis, o arquivo LeSensor.cpp com a implementação e um main.cpp para testar:

LeSensor.h:


...
#include "sensor"

class LeSensor {

...

public

LeSensor();
~LeSensor();

char *portaA = NULL;
tipoSensor *sensorA;

int iniciaSensor();

...
}

LeSensor.cpp:


...
#include "LeSensor.h"
...
LeSensor::iniciaSensor() {

char usbA[] = {"/dev/usb/hiddev0"}; //a atribuição da usb também funciona desse jeito no programa sequencial
portaA=usbA;
sensorA=fdOpen(portaA);

if (sensorA == NULL)
{
cout << "\n Iniciar sensor A falhou.\n";
}
}
...

Main:


...
#include LeSensor.h

int main(int argc, char *argv[])
{
LeSensor *obj = new LeSensor();
obj->iniciaSensor();
delete obj;

return 0;
}

Não dá erro de compilação, e se mando imprimir o valor de portaA em LeSensor.cpp aparece o valor /dev/usb/hiddev0 certinho. Mas a função iniciaSensor não está funcionando, sempre retorna NULL.

Alguma sugestão?

Compartilhar este post


Link para o post
Compartilhar em outros sites

É interessante ele compilar sem reclamar de nada, porque por exemplo, no LeSensor.cpp,

[COLOR="Red"][B]int[/B][/COLOR] LeSensor::iniciaSensor() {

você não está especificando o tipo de retorno (int) do membro iniciaSensor() muito embora tenha declarado no cabeçalho como do tipo int. Ou isso ou não sabia eu que era possível. :D Muito embora quando eu fiz o mesmo por equivoco, não compilou. Você usa o gcc pra compilar ou esse editor que você comentou anteriormente tem um compilador próprio?

Bom, deixemos isso pra lá. Afinal compila. :lol:

Você não postou toda a implementação da iniciaSensor()... assim não dá pra saber tudo o que ta rolando nela. Mas a priori evite aquela declaração com inicialização no cabeçalho:

char *portaA [COLOR="Red"][B]= NULL[/B][/COLOR];

O compilador estranhamente também não reclamou sobre isso. Deixe as inicializações pro construtor da classe LeSensor. Se não criou o construtor, então o compilador o fez por você. Tente remover aquele "= NULL" do cabeçalho e verificar se a seguinte linha está funcionando:

portaA=[COLOR="Red"][B]&[/B][/COLOR]usbA;

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
É interessante ele compilar sem reclamar de nada, porque por exemplo, no LeSensor.cpp,

[COLOR="Red"][B]int[/B][/COLOR] LeSensor::iniciaSensor() {

você não está especificando o tipo de retorno (int) do membro iniciaSensor() muito embora tenha declarado no cabeçalho como do tipo int. Ou isso ou não sabia eu que era possível. :D Muito embora quando eu fiz o mesmo por equivoco, não compilou. Você usa o gcc pra compilar ou esse editor que você comentou anteriormente tem um compilador próprio?

Bom, deixemos isso pra lá. Afinal compila. :lol:

Você não postou toda a implementação da iniciaSensor()... assim não dá pra saber tudo o que ta rolando nela. Mas a priori evite aquela declaração com inicialização no cabeçalho:

char *portaA [COLOR="Red"][B]= NULL[/B][/COLOR];

O compilador estranhamente também não reclamou sobre isso. Deixe as inicializações pro construtor da classe LeSensor. Se não criou o construtor, então o compilador o fez por você. Tente remover aquele "= NULL" do cabeçalho e verificar se a seguinte linha está funcionando:

portaA=[COLOR="Red"][B]&[/B][/COLOR]usbA;

Ops, falha minha na hora de copiar o código. Tem sim o int no cabeçalho da função, por isso compila. Ela inteira fica assim:


Int LeSensor::iniciaSensor() {
char usbA[] = {"/dev/usb/hiddev0"}; //a atribuição da usb também funciona desse jeito no programa sequencial
portaA=usbA;
sensorA=fdOpen(portaA);
if (sensorA == NULL) {
cout << "\n Iniciar sensor A falhou.\n";
usleep (50000);
return -1;
}
cout << "\n Sensor iniciado.\n";
}

Sobre o Null, nem tinha reparado pois foi na base do ctrl c ctrl v e junto com a ferrugem na POO, deu nisso.

Estou usando o g++ 4.7 pra compilar via terminal. Abandonei de vez o netbeans, era muita complicação desnecessária.

Amanhã vou testar a atribuição com & e posto o resultado aqui. Não tenho certeza se testei do jeito que você passou, mas testei várias opções e combinações de atribuição e passagem com ponteiros, e todas davam erro de conversão de variável.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olhando pra função toda agora, você possui o return dentro de um if, o que quer dizer que ela vai retornar um int sob determinada condição. Mas ela deve retornar um int fora dessa condição tambem. Simplesmente porque ela deve ter um retorno do tipo int.

O teu g++ ta meio esquisito e não ta reclamando muito, hehe, mas a priori ele deveria dar o seguinte alerta:

warning: control reaches end of non-void function[-Wreturn-type]

Você tem que colocar um return num else ou fora do if-else também, no caso da função seguir por caminhos em que não haja retorno muito embora seja obrigada a retornar.

Bom, isso foi um comentário extra, claro.

Sobre a duvida inicial, eu continuo achando que é naquela linha. Afinal, você não deu o endereço da variável (através do operador &) ao ponteiro.

EDIT:

Abandonei de vez o netbeans, era muita complicação desnecessária.

Ahh, e sabia decisão. :D

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Testei aqui e realmente dá erro quando coloco &:

erro: cannot convert ‘char (*)[17]’ to ‘char*’ in assignment

E se eu coloco no programa sequencial:


char usbA[] = {"/dev/usb/hiddev0"};
portaA=usbA;
sensorA=fdOpen(portaA);

ao invés de portaA=argv[1];, funciona. Porque aí funciona e no OO não?? Isso que está estranho!

EDIT: estava comparando aqui os includes, pois pensei na possibilidade de ter alguma lib com uma função chamada fdOpen e estar dando conflito com o fdOpen da biblioteca do fabricante do sensor. O que tem a mais é a chamada para a iostream. Como sou nova no linux e no c++ não sei se existe outra função com esse nome.

Comentei o iostream e tirei tudo do código relativo a ele. Não mudou nada, infleizmente... :(

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu não conheço a fdOpen() mas ela necessita então um char* com o nome do arquivo a abrir, como as demais fopen(), certo?

Primeiro, já que você vai pro C++ puro, sugiro abandonar o uso de char e char* e adotar algo mais moderno, a std::string:

std::string usbA = "/dev/usb/hiddev0";

Basta incluir no cabeçalho a biblioteca <string> do C++. E na hora de usa-la dentro da fdOpen():

sensorA=fdOpen([COLOR="blue"]usbA.c_str()[/COLOR]);

A função c_str() retorna o valor da std::string como char*. Assim você já elimina possíveis problemas na relação de usbA e portaA; mais ainda, elimina já a própria portaA e elimina a necessidade do operador [].

Mas se prefere continuar usando as char*,

Testei aqui e realmente dá erro quando coloco &:

erro: cannot convert ‘char (*)[17]’ to ‘char*’ in assignment

Declare primeiro portaA e usbA, aponte primeiro portaA = &usbA; e só então dê o valor de usbA e use portaA dentro da fdOpen(). Assim você garante que na hora de dar o endereço de uma a outra, as duas tem o mesmo tipo char*[].

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá gente,

Eu estou acompanhando o tópico e realmente é bem estranho não estar funcionando..

Pra ser sincero, não acho que o problema seja com a questão da string. Não vejo problema com a atribuição que ela havia feito:

portaA=usbA;

sendo usbA nada mais que um C array; nesta atribuição, o endereço do primeiro elemento do vetor é passado de forma transparente ao ponteiro portaA.

Querendo explicitamente passar o endereço com o operador &, você poderia fazer:

portaA = &usbA[0];

e o resultado seria o mesmo...

Em relação à fdopen() (lower case), até existe uma na biblioteca C:

http://linux.die.net/man/3/fdopen

então, não creio que seja o problema..

Achei essa função (fdOpen) também na biblioteca de desenvolvimento que é fornecida com uma tal de luva de dados 5DT.

Então, fdOpen sempre retorna NULL no seu novo código, certo?

[]'s

LNW

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

V!olador:

Vou alterar as declarações para string para deixar padronizado. Obrigada pela dica.

LNW:

Realmente não é conflito pelo nome da função.

Na verdade comecei a desconfiar porque um programa acessa a usb e outro não. Comecei a passar o sequencial para OO passo a passo para ver se consigo ver a partir de onde para de funcionar.

Amanhã (não estou mais na máquina que tem o sensor) vou testar uma coisa que eu acho (espero-torço-tenho-fé :unsure:) que pode estar causando esse comportamento bizarro.

EDIT:

V!olador, a alteração sugerida deu erro ao usar usbA.c_str():

erro: conversão de ‘const char*’ para ‘char*’ inválida

Deixei do jeito que estava antes.

Finalmente descobri o problema depois de 3 dias quebrando a cabeça. O acesso a porta USB no linux precisa de privilégios de administrador! (_(

A passagem da USB para a função estava igual nos 2 programas, mas a execução não. Um era executado com sudo ./programa e o outro só ./programa.

Estava usando a facilidade do linux de reaproveitar comandos já digitados, quando fui digitar por conta e tirei o sudo do programa que funcionava, parou de funcionar. Só então caiu minha ficha.:P

Adicionei o sudo no programa OO e funcionou. Acho que ainda vou apanhar um bocado do linux até dominar o básico do desenvolvimento nele...

Obrigada pela ajuda (de novo) LNW e V!olador.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caso o autor necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×