I make a program using Microsoft Access 2010 ActiveX (COM) to display references of a project (.adp file):
Access::Application* app = new Access::Application(nullptr);
app->SetVisible(true);
app->OpenAccessProject("E:\\solulog_dev\\SoluTools\\app\\test\\sources\\utilitaires\\liste_aide.adp", true);
int nb_ref = app->References()->Count();
qDebug().nospace() << nb_ref << " references";
for(int ref_num = 1; ref_num <= nb_ref; ref_num++)
{
Access::Reference* ref = app->References()->Item(ref_num);
qDebug().nospace() << "Reference #" << ref_num << " : " << ref->Name() << " (" << ref->Guid() << ") : " << ref->FullPath();
}
app->CloseCurrentDatabase();
app->Quit();
But at execution, I get the right number of references (5 in this case), but any call to any property of any reference get the same error:
Debug Error!
Program: c:\Qt\5.11.1\msvc2015\bin\Qt5Cored.dll
Module: 5.11.1
File: qaxbase.cpp
Line: 3763
ASSERT: "id < 0" in file qaxbase.cpp, line 3763
It seems to failed when try accessing property through QMetaObject.
I also get a warning followed by an error on each call to "References" object. The code works (I get the right number of references), but maybe it's related:
CoCreateInstance failure (Classe non enregistrée)
QAxBase::setControl: requested control {eb106214-9c89-11cf-a2b3-00a0c90542ff} could not be instantiated
This CLSID is correctly registered and reference "Microsoft.Office.Interop.Access.ReferencesClass" as expected
Anyone can help me with this assert ?
I tried the exact same code but using QAxObject directly, not through C++ namespace generated using dumpcpp :
QAxObject* app = new QAxObject("Access.Application", nullptr);
app->setProperty("Visible", true);
app->dynamicCall("OpenAccessProject(QString, bool)", "E:\\solulog_dev\\SoluTools\\app\\test\\sources\\utilitaires\\liste_aide.adp");
QAxObject* references = app->querySubObject("References");
int nb_ref = references->property("Count").toInt();
qDebug().nospace() << nb_ref << " références";
for(int ref_num = 1; ref_num <= nb_ref; ref_num++)
{
QAxObject* reference = references->querySubObject("Item(QVariant)", ref_num);
qDebug().nospace() << "Reference #" << ref_num << " : " << reference->property("Name").toString() << " (" << reference->property("Guid").toString() << ") : " << reference->property("FullPath").toString();
}
app->dynamicCall("CloseCurrentDatabase()");
app->dynamicCall("Quit()");
delete app;
And this time, all works perfectly. Not error about bad instantiation and I get values for each reference... So I presume it is a dumpcpp error. Should I report this problem to Qt ?
Related
I have 2 QCheckbox tables, each contains 11 elements.
I declare them as following in my class :
QCheckBox *sectionTable[10];
QCheckBox *postTable[10];
For each QCheckBox, I do this
QCheckBox* checkboxA = new QCheckBox("A");
sectionTable[0] = checkboxA;
Through my test method, I would like to return the content of each element of my QCheckbox tables.
To do so, I've done this test :
/** TEST() **/
void VGCCC::test()
{
sectionTable[0]->setText("A");
sectionTable[1]->setText("B");
sectionTable[2]->setText("C");
sectionTable[3]->setText("D");
postTable[0]->setText("E");
postTable[1]->setText("F");
postTable[2]->setText("G");
postTable[3]->setText("H");
int i=0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << sectionTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull());
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty());
}
My application is compiling, and also running. But when I call the test function, my application crash.
How can we explain this problem ?
I would like to notify that I get a result in my console. It seems my test is half working, but is crashing at the end of the 1st do/while loop, when I get out of my condition.
With regard to the 11 elements: QCheckBox *sectionTable[10]; defines only 10 slots (0 through 9) for elements.
int i=0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << sectionTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull());
Has the potential to reach past ten or eleven elements. Unless the terminating condition is found earlier, there is nothing to stop sectionTable[i] from trying to read sectionTable[11] to call its text method. If it manages to survive the call to the out-of-range sectionTable[11]->text(), it will then try calling sectionTable[11]->text().isNull(). Possibly this will be survivable as well and not be NULL. In this case sectionTable[12] will be tested. This will continue until the program hits really bad memory and crashes, a null is found, or pigs become the terror of the airways we all know they truly wish to be.
Note that i is not set back to 0 after this loop, so the first postTable to be inspected in the next loop will be at the same index as the last sectionTable.
So if sectionTable[5]->text().isNull() was NULL, postTable[5] will be the first postTable indexed and inspected.
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty());
This loop has the same error in the exit condition as the sectionTable loop.
I find out how to solve the problem. As said in the answer before (#user4581301), I didn't set back my iterator i to 0.
Also, to avoid the "out of range" crash, I put a second condition which is i<sizeof(sectionTable[i]);
This is my fonctional test function :
/** TEST() **/
void VGCCC::test()
{
int i = 0;
do
{
m_testTextEdit->insertPlainText(sectionTable[i]->text());
std::cout << "SECTION TABLE " << m_materialMap[sectionTable[i]].c_str() << "\n" << std::endl;
i++;
}
while(!sectionTable[i]->text().isNull() && i<sizeof(sectionTable[i]));
i = 0;
do
{
m_testTextEdit->insertPlainText(postTable[i]->text());
std::cout << "POST TABLE " << postTable[i]->text().toStdString() << "\n" << std::endl;
std::cout << "POST TABLE " << m_materialMap[postTable[i]].c_str() << "\n" << std::endl;
i++;
}
while(!postTable[i]->text().isEmpty() && i<sizeof(postTable[i]));
}
I am a classical music fan. My music collection (mp3) has been carefully classified using "composer" (ex. "Surname name (D.O.B-D.O.D"). I frequently get the "artist" from importing the music, ripping or some online data base. Because my mobile music player (Xbox) orders only by "artist", I would like to "swap":
album_artist = artist
artist = composer
and composer would simply remain the same (and same as artist). (Visual Studio 2013, W7, taglib1.9.1):
TagLib::PropertyMap tags = f.file()->properties();
unsigned int longest = 0;
for (TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) {
if (i->first.size() > longest) {
longest = i->first.size();
}
}
cout << "-- TAG (properties) --" << endl;
for (TagLib::PropertyMap::Iterator i = tags.begin(); i != tags.end(); ++i) {
if (i->first == "COMPOSER") {
composer = i->second;
composer_key = i->first;
}
if (i->first == "ARTIST") {
artist.append(i->second);
artist_key = i->first;
}
if (i->first == "ALBUMARTIST") {
album_artist.append(i->second);
album_artist_key = i->first;
}
cout << left << std::setw(longest) << i->first << " - " << '"' << i->second << '"' << endl;
}
if (!tags.replace(album_artist_key, artist))
cout << "album_artist_key is wrong";
else
cout << "replacing " << album_artist_key << " with " << artist << endl;
if (!tags.replace(artist_key, composer))
cout << "artist is wrong";
else
cout << "replacing " << artist_key << " with " << composer << endl;
tag->setArtist(composer.toString());
f.save();
NOTE: this code was modified starting from the tagreader.cpp code found in examples of the library.
This compiles, but after execution, all ID3 tags info disappear (corruption?), as seen by windows explorer. So, I did an experiment and commented out everything that makes any change to the tag. Basically, just open the file (FileRef) and do f.save(). This alone causes the tags to disappear.
Two questions (I think I got this completely wrong ...)
Any reason why f.save would cause a metadata corruption ?
Is the idea I am following (tags.replace and the f.save) correct?
That's not corruption; Windows Explorer just still can't read ID3v2.4 tags, a standard which came out 15 years ago, and is the default in TagLib. TagLib can, however, also write ID3v2.3 tags.
So I have been at this for days, and I have no idea why a BAD_ACCESS error is thrown. Sometimes it works, sometimes it doesn't.
void xmlParser::parseXML(string file){
tinyxml2::XMLDocument doc;
if(!doc.LoadFile(file.c_str()))
{
cout << "ERROR: TINYXML2 FAILED TO LOAD" << endl;
}
//XML FILE LAYOUT:
//<item>
// <type id="laserWeapon" name="Laser Rifle">
// <tooltip>
// <stats>
//</item>
//error seems to occur on this line
tinyxml2::XMLElement* elementType = doc.FirstChildElement("item")->FirstChildElement("type");
string id = elementType->Attribute("id");
string name = elementType->Attribute("name");
cout << "id: " << id << endl;
cout << "name: " << name << endl;
}
I use
xmlparser.parseXML(xmlparser.path+"laserRifle.xml");
to load the file. Should I be parsing this as a string, or is there some null ptr I'm neglecting? I've tried to do an 'if nullptr' clause, but it still turns out an error instead of skipping over it.
Any advice on what to do? I'm completely lost with this.
// item element can be missed and you'll get bad access. Do not chain your calls that way
tinyxml2::XMLElement* elementType = doc.FirstChildElement("item")->FirstChildElement("type");
// element type can be missed, as well as attributes id and name
string id = elementType->Attribute("id");
string name = elementType->Attribute("name");
cout << "id: " << id << endl;
cout << "name: " << name << endl;
}
Carefully check every element and attribute. Do not chain calls because every call can return null. If you check all nullptr cases you'll find your error
I'm using MySQL C++ connector version 1.1.0.
This is how my code looks like:
PreparedStatement *pStatement;
connection->setAutoCommit(false);
pStatement = connection->prepareStatement("UPDATE records "
"SET is_processed = ? "
"WHERE id = ?");
//LOOP BEGIN
pStatement->setInt(1, is_processed);
pStatement->setString(2, record_id);
pStatement->execute();
//LOOP END
int updated_records;
try
{
updated_records = pStatement->getUpdateCount();
}
catch(SQLException&e)
{
cout << "ERROR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << ")" << endl;
}
connection->commit();
connection->setAutoCommit(true);
The exception is thrown with following output:
ERROR: MySQL_Prepared_Statement::getUpdateCount (MySQL error code: 0, SQLState: )
So it says totally nothing. What's wrong with getUpdateCount() function? Is there some way I can get more detailed error reporting level?
EDIT
Is there any other way to get updated rows count using mysql c++ connector?
I ran into this problem as well. I ended up taking a look at the source code. It appears that the source explicitly will throw an exception.
uint64_t
MySQL_Prepared_Statement::getUpdateCount()
{
checkClosed();
throw MethodNotImplementedException("MySQL_Prepared_Statement::getUpdateCount");
return 0; // fool compilers
}
I've finally found working solution:
int updated_records = 0;
//LOOP BEGIN
pStatement->setInt(1, is_processed);
pStatement->setString(2, record_id);
updated_records += pStatement->executeUpdate();
//LOOP END
cout << updated_records;
executeUpdate() return number of affected rows and it works without any error, so that's enough for me.
To clarify for others, because I was confused; do it like this:
pstmt = con->prepareStatement ("UPDATE localdata SET Val = ? WHERE ID = ?");
pstmt->setDouble (1, 7.77); // first "?"
pstmt->setInt (2, 0); // second "?"
pstmt->executeUpdate ();
The trick is setting the values according to their table type and order in the statement.
There is some problem during the run time of my program and i am unable to get what the problem is.
what happens basically is , my program automatically closes and displays the following in Microsoft visual c++ 2010 express window
What could be the reasons for this ? I have no idea why this is happening.
Let me tell that in my program i have used pointers too often and have used character arrays which i write to the disc
The program is too large to display
This is the function called after which my program stops :
void display_databases()
{
struct info_of_trains
{
int train_no;
char train_name[25];
char boarding_pt[25];
char destination[25];
int first_seats;
int fare_first;
int second_seats;
int fare_second;
char date[20];
};
info_of_trains e;
cout<<"TRno. TRname B.pt D.pt F.seats F.fare S.seats F.second Date\n";
FILE *fp;
fp=fopen("database","r");
if(fp==NULL)
{
cout<<"failure";
}
else
{
while(fread(&e,sizeof(e),1,fp)==1)
{
printf(e.train_no,e.train_name,e.boarding_pt,e.destination,e.first_seats,e.fare_first,e.second_seats,e.fare_second,e.date);
cout<<"-------------------------------------------------------------------------------\n";
}
fclose(fp);
}
}
This is where execution stops :!
You seem to have hit a breakpoint, or your program had an access violation (reading an illegal pointer). You also seem to have maximized/detached the debugging panels. You can reattach the panel by dragging the yellow bar at the top to the lower part of the screen.
Did you recieve a warning message before it happened? Otherwise, did you define a breakpoint (clicking in the left margin of the code editor, so a red circle appears there)
EDIT: As pointed out in the comments, the error occurs because you use printf the wrong way. Use cout instead, as you did above:
cout << e.train_no <<" " << e.train_name << " " << e.boarding_pt << " " << e.destination << " " << e.first_seats << " " << e.fare_first << " " << e.second_seats << " " << e.fare_second << " " << e.date << endl;