Embedding Python in DLL: Access violation reading location when Py_DECREF list object

2

I am trying to embed Python into an an XLL to allow Python functions to be called within Excel. An XLL is a DLL that also includes at a minimum 2 functions that tell Excel how to register or unregister the exported functions from the DLL, so this can be treated exactly as a traditional DLL. The issue I am having is when decreasing the reference count of a Python list object the program crashes with the following error:

Exception thrown at 0x1E14E37D (python37.dll) in EXCEL.EXE: 0xC0000005: Access violation reading location 0x00000064.

I do not have this issue when decreasing the reference count strings, floats, bool, etc. Only list and tuple object are giving me this issue.

Below I have made a simple example with 2 functions exposed to Excel, testFloat and testList. Both are made very simple to try and debug the issue, so the functions take no arguments and both return xltypenil to Excel, which will fill the cell with 0. Each function creates their own Python object (a float or a list) and then decrements the reference count.

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <Windows.h>
#include <XLCALL.H>
#include <FRAMEWRK.H>

LPCWCHAR uFuncs[][3]{
    {L"testFloat", L"Q", L"testFloat"},
    {L"testList", L"Q", L"testList"},
};

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

int WINAPI xlAutoOpen(void) {
    if (!Py_IsInitialized()) {
        Py_InitializeEx(0);
    }

    // register functions with Excel
    XLOPER12 xDLL;
    Excel12f(xlGetName, &xDLL, 0);
    for (int i{ 0 }; i < sizeof(uFuncs) / sizeof(uFuncs[0]); i++) {
        Excel12f(xlfRegister, 0, 4,
            (LPXLOPER12)& xDLL,
            (LPXLOPER12)TempStr12(uFuncs[i][0]),
            (LPXLOPER12)TempStr12(uFuncs[i][1]),
            (LPXLOPER12)TempStr12(uFuncs[i][2])
        );
    }
    Excel12f(xlFree, &xDLL, 0);

    return 1;
}

int WINAPI xlAutoClose(void) {
    if (Py_IsInitialized()) {
        Py_FinalizeEx();
    }
    return 1;
}

LPXLOPER12 testFloat(void) {
    static XLOPER12 xRet;
    PyObject* obj{ PyFloat_FromDouble(2.5) };
    Py_DECREF(obj);
    xRet.xltype = xltypeNil;
    return &xRet;
}

LPXLOPER12 testList(void) {
    static XLOPER12 xRet;
    PyObject* obj{ Py_BuildValue("[dd]", 3.4, 4.5) };
    Py_DECREF(obj);  // <---- This is where the debugger says the error is
    xRet.xltype = xltypeNil;
    return &xRet;
}

Currently I am getting the following error:

Exception thrown at 0x1E14E37D (python37.dll) in EXCEL.EXE: 0xC0000005: Access violation reading location 0x00000064.

I am expecting this to run with no errors and return 0 to the Excel cell calling the function.

python
c++
excel
dll
xll
asked on Stack Overflow Oct 5, 2019 by pywex • edited Oct 5, 2019 by pywex

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0