Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

Monday, January 06, 2014

C++ unsigned arithmetic gotcha

Recently I came across a piece of code that looked similar to the following:

#include

int main() {
  unsigned int a, b;

  a = 20;
  b = 30;

  double c = double(a - b);

  printf("%lf\n", c);

}


One may, at first glance assume that this would spit out the required -10.0, however this is not the case. It will print out a huge number something like 4294967286.0 !

The reason for this is that the datatype of a and b are unsigned types. And at least with the GCC compiler (or for that matter, I assume any compiler), the intermediate variable that is generated would be an unsigned type, resulting in "mis-interpretation" of the sign bit when the casting operation is performed. 

In other words, when a subtraction is performed on unsigned quantities, you should better be careful to see what actually is happening! 


Tuesday, September 18, 2012

Calling external Python function from a C/C++ routine

An aricle by Jum Du at CodeProject (see: http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I) gives a very detailed overview of how to call a Python function from C/C++ routines in an embedded interpreter using CPython interface. While this quite useful, however, one needs to keep the .py file at the same place where the C/C++ executable resides.

I needed a solution where the .py file could reside anywhere on the local file system. Turns out that the modification is quite simple, you just need to make sure that sys.path is appended with the correct path at runtime where the .py file can be found. The follwing is the pseudo(C++)-code of how I do this:

PyObject* runFunction(std::string scriptFilePath, std::string funcName, PyObject *arglist)
{
    // this code is based on http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I
    try {
        PyObject *pName, *pModule, *pDict, *pFunc, *pValue = Py_None;
        std::string thePath = // .. your code to extract the path, for '/home/ganeshv/pyfiles/my.py' : path is '/home/ganeshv/pyfiles/'
        std::string theModule =  // .. your code to extract the module, for '/home/ganeshv/pyfiles/my.py' : module is 'my'
        // printf("importing [%s] from [%s]\n", theModule.c_str(), thePath.c_str());
        // first extract the file name and file path
        std::string code = "sys.path.append(\"" + thePath + "\")\n";
        // add the path
        PyRun_SimpleString(code.c_str());
        // Build the name object
        pName = PyString_FromString(theModule.c_str());
        if (pName == Py_None) return Py_None;
        // Load the module object
        pModule = PyImport_Import(pName);
        if (pModule == Py_None) {
            Py_DECREF(pName);
            return Py_None;
        }
        // pDict is a borrowed reference
        pDict = PyModule_GetDict(pModule);
        if (pDict == Py_None) {
            Py_DECREF(pModule);
            Py_DECREF(pName);
            return Py_None;
        }
        // pFunc is also a borrowed reference
        pFunc = PyDict_GetItemString(pDict, funcName.c_str());
        if (PyCallable_Check(pFunc)) {
            pValue = PyObject_CallObject(pFunc, arglist);
        } else {
            PyErr_Print();
        } // end if
        // Clean up
        Py_DECREF(pModule);
        Py_DECREF(pName);
        return pValue;
    } catch(...) {
        return Py_None;
    }
}