Smalltalk 为什么可以';我不能通过DLL/C-Connect将一个意外的字节传递给一个空*吗?

Smalltalk 为什么可以';我不能通过DLL/C-Connect将一个意外的字节传递给一个空*吗?,smalltalk,visualworks,Smalltalk,Visualworks,我想把一个意想不到的字节传递给一个外部库,比如说 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. self isOopRef表示CPoint

我想把一个意想不到的字节传递给一个外部库,比如说

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.
self isOopRef
表示CPointerType已声明为
\u oopref*

如果我作弊并声明:

MyLibrary>>foo: buf len: len
    <C: int foo(_oopref *buf,unsigned int len)>
然后,
MyApplication新测试
工作起来很有魅力。

这不是真正的意图吗?如果原型指定指向oop的指针,则传递任何类型的非立即对象,或者传递对字节/单词/数组的引用。…

我不是VisualWorks用户,但您是否考虑过对象在调用过程中移动(因此其oop发生变化)的情况?例如,如果外部函数具有对Smalltalk的回调,则可能会发生这种情况。是的,由于重新定位,有两种可能的失败路径:回调和线程FFI调用。VW提供了一种在FixedSpace中分配缓冲区参数的方法,FixedSpace是Smalltalk内存中免于重新定位的空间。我理解用户有责任分配正确的空间。还可以通过使用临时限定符手动修补函数原型来指定外部函数需要FixedSpace中的指针,这一点稍后由CPointerType>>强制ForArgument:检查。我想负责并承担责任。与我上面写的相反,与beOopRef不同,beOopRef由_oopref限定符触发,没有限定符连接到beFixed,而且这个确保实际参数确实在FixedSpace中的功能在系统中未使用,而且不容易访问。可能还有另一个问题:对齐。extnallibrary函数可能期望传递的地址在4、8或16字节上对齐。Smalltalk位阵列数据的对齐方式可能不同。我在尝试传递double*数据时遇到了遗留squeak vm中的问题,该数据有时按4字节而不是8字节对齐……似乎_oopref是为传递指向对象数据的直接指针而设计的,而_oop是为传递指向对象头的指针而设计的。对象引擎函数oe*()需要_oop,而不是_oopref。
MyLibrary>>foo: buf len: len
    <C: int foo(_oopref *buf,unsigned int len)>
(anObject isString
    or: [self isOopRef or: [anObject class isBits and: [anObject class isVariable]]])
        ifTrue: [^anObject].