Re: [Pharo-dev] uFFI: What is the difference between FFIExternalObject and FFIOpaqueObject?
On 22 May 2020, at 04:24, Sean P. DeNigris <sean@clipperadams.com> wrote:
Esteban Lorenzano wrote
The class comments are not clear?
Maybe it's me ;-)
Esteban Lorenzano wrote
Opaque object = https://en.wikipedia.org/wiki/Opaque_data_type <https://en.wikipedia.org/wiki/Opaque_data_type> External object = a pointer to something.
For example, why is ObjCClass a subclass of FFIExternalObject instead of FFIOpaqueObject when the docs say that a "Class [is] An opaque type that represents an Objective-C class"? Also, is the distinction just conceptual? I don't see what either class "buys" you in behavior since they are siblings that both pretty much have no methods.
This is because ObjCClass = SomeOpaqueStructurePointer (is already a pointer), same as ObjCSelector and ObjCMethod. Difference is subtle, because is just a different way of representing the same. The easiest way I have to explain is: You use an OpaqueObject when you will refer to the opaque type in calls as: someFunction(opaqueobject *someArg). You use an ExternalObject when you will refer to the opaque type in calls as: someFunction(externalobject someArg). Esteban
----- Cheers, Sean -- Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html <http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html>
On Fri, 22 May 2020 at 15:25, Esteban Lorenzano <estebanlm@netc.eu> wrote:
On 22 May 2020, at 04:24, Sean P. DeNigris <sean@clipperadams.com> wrote:
Esteban Lorenzano wrote
The class comments are not clear?
Maybe it's me ;-)
No. I struggled with this also, and still don't have it fully grasped. I could follow Eteban's advice in a particular case I asked about, but still feel hard to reason about next time. http://forum.world.st/typedef-pointerArity-for-FFIOpaqueObjects-td4914975.ht... http://forum.world.st/UFFI-isPointer-absolute-or-versus-naturalPointerArity-...
Esteban Lorenzano wrote
Opaque object = https://en.wikipedia.org/wiki/Opaque_data_type <https://en.wikipedia.org/wiki/Opaque_data_type> External object = a pointer to something.
For example, why is ObjCClass a subclass of FFIExternalObject instead of FFIOpaqueObject when the docs say that a "Class [is] An opaque type that represents an Objective-C class"? Also, is the distinction just conceptual? I don't see what either class "buys" you in behavior since they are siblings that both pretty much have no methods.
This is because ObjCClass = SomeOpaqueStructurePointer (is already a pointer), same as ObjCSelector and ObjCMethod. Difference is subtle, because is just a different way of representing the same.
The easiest way I have to explain is:
As a prelude to my next comment, how does "External" distinguish between the two case? Aren't both cases dealing with external C data? You use an OpaqueObject when you will refer to "the opaque type" in calls
as: someFunction(opaqueobject *someArg). You use an ExternalObject when you will refer to "the opaque type" in calls as: someFunction(externalobject someArg).
That makes the distinction really clear. So if now IIUC, both cases deal with "opaque types" with the *only* difference between the two being the arity? Then I propose the following naming would be more intention revealing... OpaqueObject when you will refer to "the opaque type" in calls as: someFunction(opaqueobject *someArg). OpaquePointer when you will refer to "the opaque type" in calls as: someFunction(opaquepointer someArg). And to test my new understanding, the matching typdefs and FFI calls would be... OPAQUE OBJECT - typedef MyOpaqueType opaqueobject. - int someFunction(opaqueobject *someArg) - FFIOpaqueObject subclass: #MyOpaqueType. - self ffiCall: #(int someFunction( MyOpaqueType *ot ) ). - opaque type has arity 0, so FFI needs to take a pointer to it OPAQUE POINTER - typedef MyOpaqueObject *opaquepointer. - int someFunction(opaquepointer someArg) - FFIOpaquePointer subclass: # MyOpaqueType. - self ffiCall: #(int someFunction( MyOpaqueType ot ) ). - opaque type has arity of 1, so FFI uses it directly The latter FFI call is without the *⦠because FFIOpaquePointer is already a pointer. In practice, both FFI calls are identical, and you use the one that matches the C header definitions. ...or maybe I still don't get it. cheers -ben
Esteban Lorenzano wrote
The easiest way I have to explain is:
You use an OpaqueObject when you will refer to the opaque type in calls as: someFunction(opaqueobject *someArg). You use an ExternalObject when you will refer to the opaque type in calls as: someFunction(externalobject someArg).
Very clear! We're getting somewhere :) But... What if a type is used both ways? For example: ^ self ffiCall: #(Method * class_copyMethodList(Class self, uint *outCount)) and ^ self ffiCall: #(struct objc_method_description * method_getDescription(Method self)) ----- Cheers, Sean -- Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
On Sun, 24 May 2020 at 02:01, Sean P. DeNigris <sean@clipperadams.com> wrote:
Esteban Lorenzano wrote
The easiest way I have to explain is:
You use an OpaqueObject when you will refer to the opaque type in calls as: someFunction(opaqueobject *someArg). You use an ExternalObject when you will refer to the opaque type in calls as: someFunction(externalobject someArg).
Very clear! We're getting somewhere :) But...
What if a type is used both ways?
For example: ^ self ffiCall: #(Method * class_copyMethodList(Class self, uint *outCount)) and ^ self ffiCall: #(struct objc_method_description * method_getDescription(Method self))
In advance of Esteban's answer I'd like to understand better your situation above. Passing a method to a function seems like setting up a call-back? Do you have a concrete C example that can be viewed in its full context? cheers -ben
participants (3)
-
Ben Coman -
Esteban Lorenzano -
Sean P. DeNigris