Ensure LAMMPS pointer is of type c_void_p

Fixes segfaults caused by API change. The API change in
lammps_open and lammps_open_no_mpi makes them return the LAMMPS pointer
via their return value. However due to how ctypes operates, even
if restype is specified to be c_void_p, the function returns an integer.

Without the proper type of the pointer, calling functions without arglists would default
to using 32bit integers to pass an argument, which cuts away parts of the 64bit pointer.
Subsequently, resolving the truncated pointer in the library causes segfaults.

This commit fixes the root cause. But it also highlights the need of specifying
the arglists of all library functions.
This commit is contained in:
Richard Berger 2020-08-28 14:21:03 -04:00
parent caeb0af0d1
commit 6bcc263b41
No known key found for this signature in database
GPG Key ID: A9E83994E0BA0CAB
2 changed files with 7 additions and 3 deletions

View File

@ -340,7 +340,7 @@ class lammps(object):
self.opened = 1
comm_ptr = self.MPI._addressof(comm)
comm_val = MPI_Comm.from_address(comm_ptr)
self.lmp = self.lib.lammps_open(narg,cargs,comm_val,None)
self.lmp = c_void_p(self.lib.lammps_open(narg,cargs,comm_val,None))
else:
if self.has_mpi4py and self.has_mpi_support:
@ -355,10 +355,10 @@ class lammps(object):
cargs = (c_char_p*narg)(*cmdargs)
self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p*narg, \
c_void_p]
self.lmp = self.lib.lammps_open_no_mpi(narg,cargs,None)
self.lmp = c_void_p(self.lib.lammps_open_no_mpi(narg,cargs,None))
else:
self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p, c_void_p]
self.lmp = self.lib.lammps_open_no_mpi(0,None,None)
self.lmp = c_void_p(self.lib.lammps_open_no_mpi(0,None,None))
else:
# magic to convert ptr to ctypes ptr

View File

@ -1,5 +1,6 @@
import sys,os,unittest
from lammps import lammps, LMP_STYLE_GLOBAL, LMP_STYLE_ATOM, LMP_TYPE_VECTOR, LMP_TYPE_SCALAR
from ctypes import c_void_p
class PythonNumpy(unittest.TestCase):
def setUp(self):
@ -11,6 +12,9 @@ class PythonNumpy(unittest.TestCase):
def tearDown(self):
del self.lmp
def testLammpsPointer(self):
self.assertEqual(type(self.lmp.lmp), c_void_p)
def testExtractCompute(self):
self.lmp.command("region box block 0 2 0 2 0 2")
self.lmp.command("create_box 1 box")