Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Я не знаю, почему вы думаете, что map будет проблемой. Способ, которым он называется (создание списка из него ), работает одинаково в обеих версиях Python .
Posting [Python 3]: ctypes - библиотека сторонних функций для Python .
Я не могу быть на 100% уверен без документации по функциям, но по тому, как они объявлены:
olDaInitialize :
prototype = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_char_p, ctypes.POINTER(ctypes.c_ulong))
paramflags = (1, "name"), (2, "hDev")
olDaGetDASS :
prototype = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_ulong, ctypes.c_long, ctypes.c_uint, ctypes.POINTER(ctypes.c_ulong))
paramflags = (1, "hDev"), (1, "SubsystemType"), (1, "uiElementNr"), (2, "adhandle")
Я могу заключить, что возвращаемые значения представляют собой статусы выполнения функций , обычно:
Но в Initialize вы устанавливаете hDev (который выводится для olDaInitialize и вводится для olDaGetDASS ) вот так (есть также несоответствие типов, но оно скрывается автоматическим приведением):
hdev = olDaInitialize(name)
self.hdev = hdev
, поэтому вы присваиваете hdev статус olDaInitialize [ 1124], который не имеет смысла. Правильный способ сделать это:
В __ init __ :
self.hdev = ctypes.c_ulong(0)
В Initialize :
hdev = ctypes.c_ulong(0)
status = olDaInitialize(name, ctypes.byref(hdev))
if status == 0: # Or whichever value means SUCCESS
self.hdev = hdev
То же самое относится и к adhandle ( olDaGetDASS последний аргумент), на который вы ссылаетесь в GetSubsystem (как sshandle ) и, вероятно, используете другое место в коде.
Пока мы находимся в разделе улучшений:
Имя передается как __ init __ , так и ] Initialize кажется излишним. Я бы предложил оставить его в инициализаторе, а в теле сделать:
self.name = name.encode("utf-8")
, а затем удалить аргумент из Initialize и использовать self.name
внутри него
Вы используете errcheck функциональность, но сейчас это совсем не помогает. Вы можете улучшить это (например, отображая код ошибки). Подробнее о [SO]: Как использовать errcheck ctypes? (Ответ @ CristiFati)
Инициализация вызывается дважды: в основном скрипте и в setupGetSingleValue . Вы должны удалить вызов из одного места (я бы сказал, последнее)
olDaEnumBoards (и listboardscallback ) не хватает. Кроме того, где напечатаны 1 st sup> 2 строки ?
Попробуйте сохранить согласованность имен ваших идентификаторов ( [Python] : PEP 8 - Руководство по стилю для кода Python )
@ EDIT0 :
Добавление некоторых упрощенных код, чтобы проверить, воспроизводит ли проблема.
code.py :
#!/usr/bin/env python3
import sys
import ctypes
def main():
oldaapi64 = ctypes.CDLL(find_library("oldaapi64"))
olmem64 = ctypes.CDLL(find_library("olmem64"))
oldainitialize = oldaapi64.olDaInitialize
oldainitialize.argtypes = [
ctypes.c_char_p, ctypes.POINTER(ctypes.c_ulong),
]
oldainitialize.restype = ctypes.c_int
oldagetdass = olmem64.olDaGetDASS
oldagetdass.argtypes = [
ctypes.c_ulong, ctypes.c_long, ctypes.c_uint, ctypes.POINTER(ctypes.c_ulong),
]
oldagetdass.restype = ctypes.c_int
dev = ctypes.c_ulong(0)
res = oldainitialize(b"DT9818(00)", ctypes.byref(dev))
print("{:s} returned {:d}. Dev: {:d}".format(oldainitialize.name, res, dev.value))
OLSS_AD = 0
element_num = 0
handle = ctypes.c_ulong(0)
res = oldagetdass(dev, OLSS_AD, element_num, ctypes.byref(handle))
print("{:s} returned {:d}. Handle: {:d}".format(oldagetdass.name, res, handle.value))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
print("Done.")