Wednesday, January 29, 2014

Traverse C-String Char By Char

Character pointer points to the address of a single character. By accessing the next address location of the current character pointer, until it points to the '\0' char, it gives you the availability to read a whole c-string in a while loop.
Following sample project created by qt creator and contains following files:

1-TraverseC-StringCharByChar.pro
2-main.cpp



TraverseC-StringCharByChar.pro file contains project configuration.
TARGET = TraverseC-StringCharByChar
SOURCES += main.cpp

main.cpp file contains just main method which is showing how to traverse a c-string till an end-of-string character is found.

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   char* str = "C-StringToTraverse";
   cout<<"Input String = "<<str<<endl<<endl;
   while(*str)
   {
        cout << *str<<endl;
        ++str;
   }
   return 0;
}

A char* points to the start address of the c-string. By incrementing 1, the address of the char* shows the address of the next character in the c-string. While loop executes until it finds the '\0' character which is corresponding to the 0. Therefore, the while loop terminates, because the current char pointer points to 0 which equals to false.
Console output is as follows :





Monday, November 14, 2011

Call Symbol From Shared Object File (DLL) with QLibrary

    Shared libraries are represented with *.dll and *.so files on windows and unix platforms; respectively. Symbols in a shared object file (*.dll,*.so) are designed to be exported by the library writer. Client imports symbols from shared library. 
    In this sample there are two projects in the Qt Creator projects pane which are SharedLib and SharedLibClient. SharedLib is a C++ Library project which creates a shared object file (dll) with an exported symbol in it. SharedLibClient is a QT Console Application which calls SharedLib dll at runtime. In order to debug SharedLibClient project successfully, required “SharedLib.dll” file is placed under the debug folder of the SharedLibClient project.


SharedLib project contains a simple symbol which sums two integers and returns the result.
SharedLib.pro is the project configuration file and contains: 
QT       -= gui
TARGET = SharedLib
TEMPLATE = lib
DEFINES += SHAREDLIB_LIBRARY
SOURCES += Sharedlib.cpp
HEADERS += Sharedlib.h\
        SharedLib_global.h
SharedLib_global.h is created by the QT Creator IDE for the new C++ Library project and contains:
#ifndef SHAREDLIB_GLOBAL_H
#define SHAREDLIB_GLOBAL_H

#include <QtCore>

#if defined(SHAREDLIB_LIBRARY)
#  define SHAREDLIBSHARED_EXPORT Q_DECL_EXPORT
#else
#  define SHAREDLIBSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif

Sharedlib.h is the header file and contains implementation details for the Sharedlib.
#ifndef SHAREDLIB_H
#define SHAREDLIB_H

#include "SharedLib_global.h"

class SHAREDLIBSHARED_EXPORT SharedLib {
public:
    SharedLib();
    int addNumbers(int num1, int num2);
};

#endif
Sharedlib.cpp file contains the implementation for the addNumbers function.
#include "Sharedlib.h"

extern "C" __declspec(dllexport) int addNumbers(int no1, int no2)
{
    return no1+no2;
}
addNumbers(int,int) symbol is exported as a C function from the SharedLib library. Function is also wrapped in an extern "C" block. If you are building on Windows, the function needs to be explicitly exported from the DLL using the __declspec(dllexport) compiler directive.
In order to create "SharedLib" project in Qt Creator, create a "Qt Shared Library" project and add only one cpp file into it. Inside this cpp file sign your function that you are willing to export with dllexport macro. Then build the project in debug mode. After building the "SharedLib" project in debug mode by Qt Creator IDE, related dll file is generated under the "SharedLibClient\SharedLibClient-build-desktop" folder of SharedLib project for Windows platform.

In order to create "SharedLibClient" project in Qt Creator, create a simple client "Qt Console Application" that is going to use "addNumbers" function from "SharedLib.dll" library. SharedLibClient project contains simply a main.cpp file. In this main.cpp file QLibrary class of QT framework is used to load shared library (SharedLib.dll on Windows) at runtime. One of the amazing features of QLibrary is that it provides platform independent access to specific library at run-time. In order to load specific library at run-time, just give the name of the *.dll or *.so file without suffix to QLibrary constructor. In this case only the name of the library without suffix "SharedLib" is going to be enough to load it into memory.

SharedLibClient.pro is the project configuration file and contains :
QT       += core
QT       -= gui
TARGET = SharedLibClient
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
In main.cpp file, shared library function addNumbers from the SharedLib.dll is called by using the QLibrary resolve function.
#include <QCoreApplication>
#include <QLibrary>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int result = 0;
    QLibrary myLib("SharedLib");
    typedef int (*MyPrototype)(int,int);
    MyPrototype myFunction = (MyPrototype) myLib.resolve("addNumbers");
    if( myFunction )
        result = myFunction(3,2);
    if( myFunction == 0 || result == 0 ) {
        qDebug() << myLib.errorString();
        qDebug() << "Can not get result from dll!";
        myLib.unload();
        return 0;
    }
    result = result+2;
    qDebug() << result;
    myLib.unload();
    return a.exec();
}

After running the SharedLibClient project in debug mode, the result is displayed on the console output.

main function of “SharedLibClient” project accomplishes following steps sequentially :
- Loads the library by passing the library file name in the QLibrary constructor
- Declares a function pointer to the symbol
- Calls the function of the exported library by resolve function of QLibrary

If QLibrary can not load the symbol from library, then the function pointer will be assigned to 0.

Benefits of Using QLibrary to Load Shared Object (DLL) Files at Run-Time :
- You do not need to have the header and lib files to compile the application.
- Just put your dll file that you want to load at run-time next to your executable .
- Executable can start without having dll next to it because dll is going to be loaded at run-time when it is required.
- Helps to generate a smaller executable file as a result.

Thursday, October 20, 2011

Triple Pointer Operations in C++

Double pointer can be used to point to two dimensional matrix (pointer-to-pointer). If there are more than one matrices and it is required to keep track of these matrices then an additional extra pointer will be required. At his point triple-pointers can be used to point to list of two dimensional matrices.
We assume that you have got three different two-dimensional matrices as in the below picture:
Triple pointer with size of 3 and pointing to 3 different matrices:



#include <QCoreApplication>
#include <iostream>
using namespace std;

//function prototype
int** initializeMatrix(int** tempMatrix, int row, int column, int matrixCellValue);


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int size = 3;
    int*** triplePointer;

    //Allocate memory for triplePointer
    triplePointer = new int**[size];

    int rowNum = 4;
    int columnNum = 3;
    int** newMatrix = 0;

    //Assign elements to cell values of each matrix
    for(int i=0; i<size; i++)
        triplePointer[i] = initializeMatrix(newMatrix,rowNum,columnNum,i);

    //Print elements of allocated matrices
    for(int num = 0; num<size; num++) {
        for(int i=0; i<rowNum; i++) {
            for(int j=0; j<columnNum; j++) {
                    cout<<triplePointer[num][i][j];
            }
            cout << "\n";
        }
        cout << "\n";
    }

    return a.exec();


}

/*
tempMatrix: matrix to allocate
row: number of rows of the matrix
column: number of columns of the matrix
matrixCellValue: value to assign to specified cell of matrix
 */
int** initializeMatrix(int** tempMatrix, int row, int column, int matrixCellValue)
{
    tempMatrix = new int*[row];
    for(int i=0; i<row; i++)
            tempMatrix[i] = new int[column];
    for(int i=0; i<row; i++)
            for(int j=0; j<column; j++)
                    tempMatrix[i][j] = matrixCellValue;

    return tempMatrix;
}


Sample c++ console application built with qt-creator on ubuntu and the console-output is 3 different 2x2 matrices displayed. Same output is produced when built with MSVS2008 on winXP.