PDA

View Full Version : how to convert a QString into a PCHAR



digog
10th February 2011, 18:25
Hello everyone,
I have a function that the parameter is a PCHAR.
So how can I convert a QString into a PCHAR to pass it as a parameter in my function?

To be more clear, that's the text I am trying to pass:

QString vid_pid = "vid_04d8&pid_1510";

And that's my function:

DWORD *MPUSBGetDeviceCount(PCHAR pVID_PID);

Any Ideas?

squidge
10th February 2011, 18:35
QString vid_pid = "vid_04d8&pid_1510";

x = MPUSBGetDeviceCount(vid_pid.toLocal8Bit().constDat a());

digog
10th February 2011, 19:36
QString vid_pid = "vid_04d8&pid_1510";

x = MPUSBGetDeviceCount(vid_pid.toLocal8Bit().constDat a());


What the diference between do what you said e do it:


QString vid_p = "vid_04d8&pid_1510"; // VID e PID

PCHAR vid_pid = vid_p.toLocal8Bit().constData();

x = MPUSBGetDeviceCount(vid_pid);


Because it's not working for me. I get the following error:
- invalid conversion from 'const char*' to 'CHAR*' in the third line.


I tried to do as you said now and I get the same error message

stampede
10th February 2011, 19:56
PCHAR vid_pid = vid_p.toLocal8Bit().constData();
Because 'vid_p.toLocal8Bit().constData()' returns 'const char*' and PCHAR is 'char*' ( CHAR is just a typedef for 'char' ).
Will this function 'MPUSBGetDeviceCount(PCHAR param)' change the 'param' ?
If yes, then you need to make a local copy of string returned by 'toLocal8Bit().constData()' and pass the copy as parameter.
Otherwise you can try to cast 'const char*' to 'char*'.

squidge
10th February 2011, 19:57
use .data instead of .constData



QString vid_pid = "vid_04d8&pid_1510";

x = MPUSBGetDeviceCount(vid_pid.toLocal8Bit().data());


Not however that this will NOT work:



QString vid_p = "vid_04d8&pid_1510"; // VID e PID

PCHAR vid_pid = vid_p.toLocal8Bit().data(); // or .constData

x = MPUSBGetDeviceCount(vid_pid);


It'll compile, but the pointer will be invalid as the intermediate QByteArray will be destroyed, therefore you need to do it as above in the one line or assign to a QByteArray yourself that is more permanent:



QByteArray ba_vid_pid = vid_p.toLocal8Bit();
PCHAR vid_pid = ba_vid_pid.data();

x = MPUSBGetDeviceCount(vid_pid); // OK

digog
10th February 2011, 20:56
First of all, thanks for the help.

I tried to do as you said here:

use .data instead of .constData



QString vid_pid = "vid_04d8&pid_1510";

x = MPUSBGetDeviceCount(vid_pid.toLocal8Bit().data());

but still did not work. So when I wrote the QString as const QString it worked.
Like this:
file.h

...
const QString vid_pid = "vid_04d8&pid_1510";
...
file.cpp

...
x = MPUSBGetDeviceCount(vid_pid.toLocal8Bit().data());
...

When I tried to do what you said here it didnt work


It'll compile, but the pointer will be invalid as the intermediate QByteArray will be destroyed, therefore you need to do it as above in the one line or assign to a QByteArray yourself that is more permanent:



QByteArray ba_vid_pid = vid_p.toLocal8Bit();
PCHAR vid_pid = ba_vid_pid.data();

x = MPUSBGetDeviceCount(vid_pid); // OK


I did like this:
file.h

...
QString vid_p = "vid_04d8&pid_1510";
QByteArray ba_vid_pid = vid_p.toLocal8Bit();
PCHAR vid_pid = ba_vid_pid.data();
...
file.cpp

...
x = MPUSBGetDeviceCount(vid_pid);
...
And I get the error message: "collect2: ld returned 1 exit status"

stampede
10th February 2011, 22:15
And I get the error message: "collect2: ld returned 1 exit status"
Probably linker could not find needed files, could you show us your .pro file ?
If you have a line in your .pro

LIBS += -l<dll name>
then you should add

LIBS += -L"path/to/dir/with/dll/file"
in order to point the linker to directory where it should search for the referenced libraries.

squidge
10th February 2011, 22:28
Can you post your entire build log? Typically there is more than one error when you get "ld returned 1 error status".

Secondly, I would advise against putting executable statements in header files, unless they are part of inline class methods.

Also, if you could be a bit more informative instead of "It didn't work", would could try to help more.

digog
10th February 2011, 23:45
Ok, I will write my entire code here.
testempusbapi.pro

TARGET = testempusbapi
TEMPLATE = app
SOURCES += main.cpp \
testempusb.cpp \
picconnector.cpp
HEADERS += testempusb.h \
mpusbapi.h \
picconnector.h

picconnector.h

#ifndef PICCONNECTOR_H
#define PICCONNECTOR_H

#include <QWidget>
#include <windows.h>

const DWORD MAXSIZE = 64;
const BYTE PING = 0x05;
//const PCHAR vid_pid = "vid_04d8&pid_1510"; // VID e PID
//const PCHAR out_pipe = "\\MCHP_EP1";
//const PCHAR in_pipe = "\\MCHP_EP1";

const QString vid_pid = "vid_04d8&pid_1510"; // VID e PID --tem q ser convertido para PCHAR quando for chamado usado .toLocal8Bit().data
const QString out_pipe = "\\MCHP_EP1"; // --tem q ser convertido para PCHAR quando for chamado usado .toLocal8Bit().data
const QString in_pipe = "\\MCHP_EP1"; // --tem q ser convertido para PCHAR quando for chamado usado .toLocal8Bit().data

// QByteArray ba_vid_pid = vid_p.toLocal8Bit();
// QByteArray ba_out_pipe = out_p.toLocal8Bit();
// QByteArray ba_in_pipe = in_p.toLocal8Bit();

// PCHAR vid_pid = ba_vid_pid.data();
// PCHAR out_pipe = ba_out_pipe.data();
// PCHAR in_pipe = ba_in_pipe.data();

class PICConnector : public QWidget
{

public:
PICConnector(QWidget *parent = 0);
virtual ~PICConnector();
bool Open();
void Close();
void LoadDLL();
DWORD SendData(PVOID SendData, DWORD SendLength, PVOID ReceiveData,
PDWORD ReceiveLength, DWORD SendDelay, DWORD ReceiveDelay);
DWORD getDLLversion();
void CheckInvalidHandle();

private:
//USB
HINSTANCE hinstLib;
HANDLE myOutPipe;
HANDLE myInPipe;
};

#endif // PICCONNECTOR_H

picconnector.cpp

#include <QtGui>
#include <stdlib.h>
#include <stdio.h>
#include "picconnector.h"
#include "mpusbapi.h"

PICConnector::PICConnector(QWidget *parent)
: QWidget(parent)
{
LoadDLL();
myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
}

//--------------------------------------------------------------------------------

// Load DLL file
void PICConnector::LoadDLL()
{

hinstLib = LoadLibrary(TEXT("mpusbapi.dll"));
if (hinstLib == NULL) {
printf("ERROR: unable to load DLL\n");
QMessageBox::warning(this, tr("LoadLibrary"),
tr("ERROR: unable to load DLL"),
QMessageBox::Ok);
FreeLibrary(hinstLib);
}
// Get function pointer
else{
MPUSBGetDLLVersion=(DWORD(*)(void))\
GetProcAddress(hinstLib,"_MPUSBGetDLLVersion");

MPUSBGetDeviceCount=(DWORD(*)(PCHAR))\
GetProcAddress(hinstLib,"_MPUSBGetDeviceCount");
MPUSBOpen=(HANDLE(*)(DWORD,PCHAR,PCHAR,DWORD,DWORD ))\
GetProcAddress(hinstLib,"_MPUSBOpen");
MPUSBWrite=(DWORD(*)(HANDLE,PVOID,DWORD,PDWORD,DWO RD))\
GetProcAddress(hinstLib,"_MPUSBWrite");
MPUSBRead=(DWORD(*)(HANDLE,PVOID,DWORD,PDWORD,DWOR D))\
GetProcAddress(hinstLib,"_MPUSBRead");
MPUSBReadInt=(DWORD(*)(HANDLE,PVOID,DWORD,PDWORD,D WORD))\
GetProcAddress(hinstLib,"_MPUSBReadInt");
MPUSBClose=(BOOL(*)(HANDLE))GetProcAddress(hinstLi b,"_MPUSBClose");

if((MPUSBGetDeviceCount == NULL) || (MPUSBOpen == NULL) ||
(MPUSBWrite == NULL) || (MPUSBRead == NULL) ||
(MPUSBClose == NULL) || (MPUSBGetDLLVersion == NULL) ||
(MPUSBReadInt == NULL)){
QMessageBox::warning(this, "LoadDLL",
tr("ERROR: unable to find DLL function"),
QMessageBox::Ok);
FreeLibrary(hinstLib);
}
}
//FreeLibrary(hinstLib);
}

//--------------------------------------------------------------------------------


PICConnector::~PICConnector()
{
if (myOutPipe != INVALID_HANDLE_VALUE)
MPUSBClose(myOutPipe);
if ( myInPipe != INVALID_HANDLE_VALUE)
MPUSBClose(myInPipe);

myOutPipe = myInPipe = INVALID_HANDLE_VALUE;

// Always check to close the library too.
if (hinstLib != NULL) FreeLibrary(hinstLib);

}

//--------------------------------------------------------------------------------
// retorna true se conseguiu abrir(inicializar) o dispositivo

bool PICConnector::Open()
{

// Always open one device only

if (MPUSBGetDeviceCount(vid_pid.toLocal8Bit().data()) > 0) {


myOutPipe = MPUSBOpen(0,vid_pid.toLocal8Bit().data(),out_pipe. toLocal8Bit().data(),MP_WRITE,0);
myInPipe = MPUSBOpen(0,vid_pid.toLocal8Bit().data(),out_pipe. toLocal8Bit().data(),MP_READ,0);

if(myOutPipe == INVALID_HANDLE_VALUE || myInPipe == INVALID_HANDLE_VALUE)
{
QMessageBox::warning(this, tr("MPUSBOpen"),
tr("ERROR: Failed to open data pipes"),
QMessageBox::Ok);
return FALSE;
}//end if

// testa a conexão - envia ping
// DWORD ReceiveLength, SentLength;
//
// byte send_buffer[1];
// byte recv_buffer[1];
// send_buffer[0] = PING;
// MPUSBWrite(myOutPipe,send_buffer,1,&SentLength,1000);
// MPUSBRead(myInPipe,recv_buffer,MAXSIZE,&ReceiveLength,1000);
// if ((ReceiveLength!=1)|(recv_buffer[0]!=PING)){
// QMessageBox::warning(this, tr("Teste Conexao"),
// tr("ERROR: O teste de conexao falhou\n"),
// QMessageBox::Ok);
// }
}
else {
QMessageBox::warning(this, tr("MPUSBGetDeviceCount"),
tr("ERROR: No devices connected"),
QMessageBox::Ok);
return FALSE;
}
return TRUE;
}

//--------------------------------------------------------------------------------

void PICConnector::Close()
{
MPUSBClose(myOutPipe);
MPUSBClose(myInPipe);
myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
}

//--------------------------------------------------------------------------------

DWORD PICConnector::getDLLversion()
{
return MPUSBGetDLLVersion();
}

//--------------------------------------------------------------------------------

// envia "data" e le o que foi enviado para checar que foi transmitido corretamente
DWORD PICConnector::SendData(PVOID SendData, DWORD SendLength, PVOID ReceiveData,
PDWORD ReceiveLength, DWORD SendDelay, DWORD ReceiveDelay)
{
DWORD SentDataLength;
DWORD ExpectedReceiveLength = *ReceiveLength;

if(myOutPipe != INVALID_HANDLE_VALUE && myInPipe != INVALID_HANDLE_VALUE)
{
if(MPUSBWrite(myOutPipe,SendData,SendLength,&SentDataLength,SendDelay))
{

if(MPUSBRead(myInPipe,ReceiveData, ExpectedReceiveLength,
ReceiveLength,ReceiveDelay))
{
if(*ReceiveLength == ExpectedReceiveLength)
{
return 1; // Success!
}
else if(*ReceiveLength < ExpectedReceiveLength)
{
return 2; // Partially failed, incorrect receive length
}//end if else
}
else
CheckInvalidHandle();
}
else
CheckInvalidHandle();
}//end if

return 0; // Operation Failed
}//end SendReceivePacket

//--------------------------------------------------------------------------------

void PICConnector::CheckInvalidHandle()
{
if(GetLastError() == ERROR_INVALID_HANDLE)
{
// Most likely cause of the error is the board was disconnected.
MPUSBClose(myOutPipe);
MPUSBClose(myInPipe);
myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
}//end if
else
QMessageBox::warning(this, tr("LoadLibrary"),
tr("Error Code %1").arg(QString::number(GetLastError(),16)),
QMessageBox::Ok);
}//end CheckInvalidHandle


testempusb.h

#ifndef TESTEMPUSB_H
#define TESTEMPUSB_H

#include <QWidget>
#include <windows.h>

class PICConnector;
class QLineEdit;
class QPushButton;
class QLabel;

class testempusb : public QWidget
{
Q_OBJECT

public:
testempusb(QWidget *parent = 0);

private slots:
void Send();
void ShowDLLversion();

private:
QLabel *label;
QLabel *label2;
QLineEdit *lineEdit;
QLineEdit *lineEdit2;
QPushButton *okButton;
QPushButton *sendButton;

PICConnector *device;
};

#endif // TESTEMPUSB_H


testempusb.cpp

#include <QtGui>
#include "testempusb.h"
#include "picconnector.h"

testempusb::testempusb(QWidget *parent)
: QWidget(parent)

{
device = new PICConnector;
label = new QLabel(tr("Get DLL Version:"));
label2 = new QLabel(tr("Data to Send(00-FF):"));
lineEdit = new QLineEdit;
lineEdit2 = new QLineEdit;
label->setBuddy(lineEdit);
label2->setBuddy(lineEdit2);
okButton = new QPushButton(tr("&Ok"));
sendButton = new QPushButton(tr("&Send"));
connect(okButton, SIGNAL(clicked()),this, SLOT(ShowDLLversion()));
connect(sendButton,SIGNAL(clicked()),this,SLOT(Sen d()));

QHBoxLayout *firstLayout = new QHBoxLayout;
firstLayout->addWidget(label);
firstLayout->addWidget(lineEdit);
firstLayout->addWidget(okButton);

QHBoxLayout *secondLayout = new QHBoxLayout;
secondLayout->addWidget(label2);
secondLayout->addWidget(lineEdit2);
secondLayout->addWidget(sendButton);

QVBoxLayout *boxLayout = new QVBoxLayout;
boxLayout->addLayout(firstLayout);
boxLayout->addLayout(secondLayout);
setLayout(boxLayout);

}

//--------------------------------------------------------------------------------

void testempusb::ShowDLLversion()
{
DWORD temp = device->getDLLversion();

int aux1 = HIWORD(temp)>>8;
int aux2 = HIWORD(temp) & 0xFF;
int aux3 = LOWORD(temp)>>8;
int aux4 = LOWORD(temp) & 0xFF;

lineEdit->setText( tr("MPUSBAPI Version:%1.%2.%3.%4").arg(QString::number(aux1,10))
.arg(QString::number(aux2,10)).arg(QString::number (aux3,10))
.arg(QString::number(aux4,10)));
}

//--------------------------------------------------------------------------------

void testempusb::Send()
{
sendButton->setDisabled(true);
if (device->Open()){

BYTE send_buf[64],receive_buf[64];
DWORD RecvLength=1;

send_buf[0] = PING;
bool ok;
send_buf[1] = lineEdit2->text().toInt(&ok,16);

if( device->SendData(send_buf,2,receive_buf,&RecvLength,1000,1000) == 1){ //testar ==0

if(RecvLength != 1 || receive_buf[0] != PING ){
QMessageBox::warning(this, tr("Send"),
tr("Failed to transmit DATA"),
QMessageBox::Ok);
}
else{
QMessageBox::warning(this, tr("Send"),
tr("Dados transmitidos com sucesso!"),
QMessageBox::Ok);
}
}
}
device->Close();
sendButton->setEnabled(true);
}


Thats all. As I said before the code only compiled when I wrote the QString as const QString in the picconnector.h file.