Почему я не могу передать UninterpretedBytes в пустое * через DLL/C-Connect?
Я хотел бы передать UninterpretedBytes во внешнюю библиотеку, сказать что-то вроде этого
MyLibrary>>foo: buf len: len
<C: int foo(void *buf,unsigned int len)>
MyApplication>>test
buffer := UninterpretedBytes new: 4.
^MyLibrary new foo: buffer len: buffer size.
Но это не в CPointerType>>coerceForArgument:anObject
,
Я знаю, что я мог бы использовать buffer gcCopyToHeap
но я не хочу
Я хочу обработать объект в памяти Smalltalk с адресом на основе Smalltalk 1, без дополнительной копии или каких-либо других сложностей.
Я нахожу последние строки CPointerType>>coerceForArgument:anObject
suspiscious:
(anObject isString
or: [self isOopRef and: [anObject class isBits and: [anObject class isVariable]]])
ifTrue: [^anObject].
self isOopRef
означает, что CPointerType был объявлен как _oopref *
,
Если я обманываю и заявляю:
MyLibrary>>foo: buf len: len
<C: int foo(_oopref *buf,unsigned int len)>
затем MyApplication new test
работает, как и ожидалось, но я не хочу обманывать, прототипы автоматически извлекаются из заголовков C, и я не хочу их исправлять вручную.
self isOopRef
семантически означает, что это ссылка на объектно-ориентированный указатель.
Каждый объект может рассматриваться как объектно-ориентированный указатель и, следовательно, может передаваться по ссылке на такой объект. _oopref *
, за исключением непосредственных объектов, таких как SmallInteger SmallDouble Character. Выше в коде есть охранник для проверки того случая, когда anObject isImmediate
на этом этапе anObject
это определенно упс
Таким _oopref можно манипулировать изнутри внешнего C-кода, например, с помощью некоторой функции Object Engine oe*(), и это не ограничивается массивами байтов / слов / двойных слов!
Охрана and: [anObject class isBits and: [anObject class isVariable]]
таким образом нет смысла.
Если я изменю последние строки CPointerType>>coerceForArgument:anObject
в:
(anObject isString
or: [self isOopRef or: [anObject class isBits and: [anObject class isVariable]]])
ifTrue: [^anObject].
затем MyApplication new test
работает как шарм.
Разве это не было настоящим намерением? Передайте любой тип не немедленного объекта, если в прототипе указан указатель на oop, или передайте ссылку на массив байтов / слов /...