Почему ctypes.c_int больше обычного int ()? [Дубликат]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

3
задан Bhargav Rao 30 November 2014 в 14:35
поделиться

3 ответа

Если вы хотите узнать подробности, вы должны взглянуть на objects.h (особенно комментарии в верхней части файла). Ваш ctypes.c_byte(1) является объектом Python:

>>> import sys
>>> import ctypes
>>> isinstance(ctypes.c_byte(1), object)
True

Как отмечено @Daniel, sys.getsizeof получает размер этого объекта Python. Этот объект Python больше, чем соответствующий объект в C. Обратите внимание на следующее из комментариев object.h:

Objects are structures allocated on the heap. . . .
The actual memory allocated for an object
contains other data that can only be accessed after casting the pointer
to a pointer to a longer structure type.  This longer type must start
with the reference count and type fields; the macro PyObject_HEAD should be
used for this.

Другими словами, макрос PyObject_HEAD прикреплен к началу каждого объекта. Это увеличивает размер объекта Python.

ctypes.sizeof, с другой стороны, возвращает фактический размер типа данных C, который находится внутри объекта Python (с использованием оператора C sizeof), .

EDIT

В свете вашей цели, которую вы упомянули в своем комментарии к сообщению Даниэля, можно отправить один байт через сервер в Python 3.x. Ниже приведен пример того, как вы должны отправить байт, используя модуль socket Python, чтобы доказать эту точку.

Вот сервер, который вы будете запускать в одном интерпретаторе Python:

# Server
import socket

HOST = ''                      # All available interfaces
PORT = 50007                   # Same port as client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
    data = conn.recv(1)        # receive data with bufsize 1; a larger bufsize will break this code
    if not data: break
    conn.sendall(data)
conn.close()

Вот клиент, который вы будете запускать в другом интерпретаторе python:

# Client
import socket

HOST = '127.0.0.1'             # The remote host, but here using localhost
PORT = 50007                   # The port used by both the client and server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'1')                # a bytes object
data = s.recv(1)               # Receive data from the socket with bufsize of 1
s.close()
print('Received', repr(data))  # confirm receipt
1
ответ дан πόδας ὠκύς 18 August 2018 в 21:28
поделиться
  • 1
    да, я догадался, что это произошло, когда я упомянул обертку объекта, так что, только если он передан на фактически код C, он будет считаться размером ctypes? – Newbie 30 November 2014 в 19:53
  • 2
    @Newbie Да, в определенной степени. Я вижу ваш комментарий в сообщении Дэниела, и вы можете достичь своей цели через Python 3.x. Я обновлю свой пост, чтобы показать вам, как это сделать. – πόδας ὠκύς 30 November 2014 в 21:34
  • 3
    Большое спасибо, я на самом деле пробовал это раньше, но это не сработало, должно быть, что-то не так с моим кодом, так как ваша работа отлично :) спасибо! – Newbie 2 December 2014 в 15:11
  • 4
    @Newbie Рад помочь, и я рад, что ты думал по тому же пути. Приветствия. – πόδας ὠκύς 2 December 2014 в 16:44

sys.getsizeof возвращает размер объекта python, это не имеет никакого отношения к размеру типа данных C. И вам ничего не нужно беспокоиться.

1
ответ дан Daniel 18 August 2018 в 21:28
поделиться
  • 1
    У меня есть задание, и я должен отправить только 2 байта через UDP-пакет, и это отчасти разочаровывает, так как я не могу найти способ хранить всего пару байтов в переменной, поэтому не нужно было выбирать python для этого тип задания? но невозможно, чтобы python не смог выполнить эту задачу – Newbie 30 November 2014 в 19:48
  • 2
    Как вы отправляете свои байты? Просто используйте bytestring. ctypes предназначен только для общения с иностранными библиотеками на других языках. – Daniel 30 November 2014 в 19:51

Модуль ctypes используется для создания и управления типами данных C в Python. Вот почему ctypes.sizeof (ctypes.c_byte (1)) возвращает 1.

>>> import sys
>>> help(sys.getsizeof) Help on built-in function getsizeof in module sys:

getsizeof(...)
    getsizeof(object, default) -> int

    Return the size of object in bytes.

, а

>>> import ctypes
>>> help(ctypes.sizeof)
Help on built-in function sizeof in module _ctypes:

sizeof(...)
    sizeof(C type) -> integer
    sizeof(C instance) -> integer
    Return the size in bytes of a C instance

>>>
1
ответ дан kvivek 18 August 2018 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: