为什么我不能通过DLL / C-Connect将UninterpretedBytes传递给void?

时间:2018-03-28 21:41:59

标签: smalltalk visualworks

我想将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的最后一行是可疑的:

(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绝对是一个oop。

这样的_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的指针,则传递任何类型的非立即对象,或者传递对bytes / words /...的数组的引用。

0 个答案:

没有答案