Why can't I pass an UninterpretedBytes to a void* thru DLL/C-Connect?

孤者浪人 提交于 2019-12-11 01:09:09

问题


I'd like to pass an UninterpretedBytes to an external library, say something like this

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.

But this fails in CPointerType>>coerceForArgument:anObject.

I know that I could use buffer gcCopyToHeap but I don't want to.
I want to handle an object in Smalltalk memory with Smalltalk 1-based address and no extra copy nor any other complication.

I find the last lines of CPointerType>>coerceForArgument:anObject suspiscious:

(anObject isString
    or: [self isOopRef and: [anObject class isBits and: [anObject class isVariable]]])
        ifTrue: [^anObject].

self isOopRef means that the CPointerType has been declared as _oopref *.
If I cheat and declare:

MyLibrary>>foo: buf len: len
    <C: int foo(_oopref *buf,unsigned int len)>

then MyApplication new test works as expected, but I don't want to cheat, the prototypes are extracted automatically from C headers and I don't want to patch them manually.

self isOopRef semantically means is a reference to an Object Oriented Pointer.
Every Object can be viewed as an Object Oriented Pointer and can thus be passed by reference to such _oopref *, except immediate objects like SmallInteger SmallDouble Character. There is a guard above in code to check for the case when anObject isImmediate, so at this stage, anObject is definitely an oop.

Such _oopref could be manipulated from within the external C-code, for example thru some Object Engine function oe*(), and this is not limited to arrays of bytes/words/double words!
The guard and: [anObject class isBits and: [anObject class isVariable]] thus makes no sense.

If I modify the last lines of CPointerType>>coerceForArgument:anObject into:

(anObject isString
    or: [self isOopRef or: [anObject class isBits and: [anObject class isVariable]]])
        ifTrue: [^anObject].

Then MyApplication new test works like a charm.
Wasn't it the real intention? Pass either any kind of non immediate object if the prototype specifies a pointer to an oop, or pass a reference to an array of bytes/words/...

来源:https://stackoverflow.com/questions/49544642/why-cant-i-pass-an-uninterpretedbytes-to-a-void-thru-dll-c-connect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!