#smalltalk #visualworks
#smalltalk #visualworks
Вопрос:
Некоторые функции C возвращаются aCPointer
к a C struct
. Это C struct
известно.
Теперь я хочу поместить C struct
в ByteArray
. В основном скопируйте содержимое структуры в a ByteArray
.
В GemStone / S это можно сделать с помощью:
CByteArray fromCPointer: aCPointer numBytes: 120.
«это создает aCByteArray с содержимым структуры, на которую ссылается CPointer (копирование только 120 байт)»
Есть ли что-то подобное в Visual Works? Я его еще не нашел. Можно было бы реплицировать структуру C на уровне Visual Works, но это только одна структура, и ее можно обрабатывать на низком уровне.
Ответ №1:
Есть только довольно уродливые #copyAt:to:size:startingAt:
, которые вы можете отправить указателю. Вам нужно выделить ByteArray
себя (убедитесь, что он достаточно большой).
answer := ByteArray new: size.
pointer
copyAt: 0
to: answer
size: size
startingAt: 1.
Другой способ (ByteArray -> Указатель) будет выполнен с помощью #copyAt:from:size:startingAt:
.
Этот метод работает для обоих ByteArray
и UninterpretedBytes
. Если вы хотите считывать данные из байтов, UninterpretedBytes
это может быть более полезным, поскольку вы можете отправлять такие вещи, как #longAt:
чтение a long
из смещения.
Комментарии:
1. Неинтерпретированные байты очень удобны. Как бы то ни было, если структура C выглядит так: struct FileAttr {char * name; char * longname; uint32_t флаги; uint8_t тип; uint64_t размер; char * owner;} fileAttr; Я могу прочитать все значения выше, но не «владелец». aCPointer>> at: и aCPointer>>copyAt:to:size:startingAt: не получает значение «владелец». Что довольно странно, потому что я могу читать другие значения.
2. К «владельцу» можно получить доступ с помощью aCPointer по адресу: 8, где 8 = byteNumberWhereTheOwnerAddressStart / 4
3. вам определенно следует подумать о том, чтобы просто определить C-Struct в вашем
ExternalInterface
. Гораздо проще получить доступ к элементам в структуре черезmemberAt:
, чем самостоятельно возиться со смещениями. Вы должны взглянутьDLLandCConnectGuide.pdf
наdoc
папку вашей установки VisualWorks. Главы 2 и 3 должны охватывать проблему, которую вы пытаетесь решить.
Ответ №2:
Если aCPointer
указывает на структуру символа *, например:
struct Names
{char * name;
char * longname;} name;
Затем:
(aCPointer at: 0) copyCStringFromHeap. "answer [name]"
(aCPointer at: 1) copyCStringFromHeap. "answer [longname]"
Для структур с символом * это работает хорошо, не тестировалось с другими типами C.