Thanks very much to @MRAB for taking time to answer. I changed my code to conform to your answer (as best I understand your comments on references), but I still get the same error. My comments continue below the new code immediately below.
int64_t Get_LibModules(int64_t * return_array) { PyObject * pName_random = PyUnicode_FromString("random"); PyObject * pMod_random = PyImport_Import(pName_random); Py_INCREF(pName_random); Py_INCREF(pMod_random); if (pMod_random == 0x0){ PyErr_Print(); return 1;} PyObject * pAttr_seed = PyObject_GetAttrString(pMod_random, "seed"); PyObject * pAttr_randrange = PyObject_GetAttrString(pMod_random, "randrange"); Py_INCREF(pAttr_seed); Py_INCREF(pAttr_randrange); return_array[0] = (int64_t)pAttr_seed; return_array[1] = (int64_t)pAttr_randrange; return 0; } int64_t C_API_2(PyObject * pAttr_seed, Py_ssize_t value_1) { PyObject * value_ptr = (PyObject * )value_1; PyObject * p_seed_calc = PyObject_CallFunctionObjArgs(pAttr_seed, value_ptr, NULL); if (p_seed_calc == 0x0){ PyErr_Print(); return 1;} //Prepare return values long return_val = PyLong_AsLong(p_seed_calc); return return_val; } So I incremented the reference to all objects in Get_LibModules, but I still get the same segfault at PyObject_CallFunctionObjArgs. Unfortunately, reference counting is not well documented so I’m not clear what’s wrong. Sep 29, 2022, 10:06 by pyt...@mrabarnett.plus.com: > On 2022-09-29 16:54, Jen Kris via Python-list wrote: > >> Recently I completed a project where I used PyObject_CallFunctionObjArgs >> extensively with the NLTK library from a program written in NASM, with no >> problems. Now I am on a new project where I call the Python random library. >> I use the same setup as before, but I am getting a segfault with >> random.seed. >> >> At the start of the NASM program I call a C API program that gets PyObject >> pointers to “seed” and “randrange” in the same way as I did before: >> >> int64_t Get_LibModules(int64_t * return_array) >> { >> PyObject * pName_random = PyUnicode_FromString("random"); >> PyObject * pMod_random = PyImport_Import(pName_random); >> > Both PyUnicode_FromString and PyImport_Import return new references or null > pointers. > >> if (pMod_random == 0x0){ >> PyErr_Print(); >> > > You're leaking a reference here (pName_random). > >> return 1;} >> >> PyObject * pAttr_seed = PyObject_GetAttrString(pMod_random, "seed"); >> PyObject * pAttr_randrange = PyObject_GetAttrString(pMod_random, >> "randrange"); >> >> return_array[0] = (int64_t)pAttr_seed; >> return_array[1] = (int64_t)pAttr_randrange; >> > > You're leaking 2 references here (pName_random and pMod_random). > >> return 0; >> } >> >> Later in the same program I call a C API program to call random.seed: >> >> int64_t C_API_2(PyObject * pAttr_seed, Py_ssize_t value_1) >> { >> PyObject * p_seed_calc = PyObject_CallFunctionObjArgs(pAttr_seed, value_1); >> > > It's expecting all of the arguments to be PyObject*, but value_1 is > Py_ssize_t instead of PyObject* (a pointer to a _Python_ int). > > The argument list must end with a null pointer. > > It returns a new reference or a null pointer. > >> >> if (p_seed_calc == 0x0){ >> PyErr_Print(); >> return 1;} >> >> //Prepare return values >> long return_val = PyLong_AsLong(p_seed_calc); >> > You're leaking a reference here (p_seed_calc). > >> return return_val; >> } >> >> The first program correctly imports “random” and gets pointers to “seed” and >> “randrange.” I verified that the same pointer is correctly passed into >> C_API_2, and the seed value (1234) is passed as Py_ssize_t value_1. But I >> get this segfault: >> >> Program received signal SIGSEGV, Segmentation fault. >> 0x00007ffff64858d5 in _Py_INCREF (op=0x4d2) at ../Include/object.h:459 >> 459 ../Include/object.h: No such file or directory. >> >> So I tried Py_INCREF in the first program: >> >> Py_INCREF(pMod_random); >> Py_INCREF(pAttr_seed); >> >> Then I moved Py_INCREF(pAttr_seed) to the second program. Same segfault. >> >> Finally, I initialized “random” and “seed” in the second program, where they >> are used. Same segfault. >> >> The segfault refers to Py_INCREF, so this seems to do with reference >> counting, but Py_INCREF didn’t solve it. >> >> I’m using Python 3.8 on Ubuntu. >> >> Thanks for any ideas on how to solve this. >> >> Jen >> > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list