-
Notifications
You must be signed in to change notification settings - Fork 71
[[Bugfix 21530]] Add more FFI examples to the Extending LiveCode Guide #1993
base: develop
Are you sure you want to change the base?
Conversation
…uide The "Extending LiveCode" user guide has been updated to include two more examples of using the FFI to bind to C functions: * another example of using a function from the C standard library * an example of binding to a function from Apple's C-based APIs with macOS
A new subsection to the C FFI section of the "Extending LiveCode" guide has been added with new information about binding to functions that are part of LiveCode's foundation library (libfoundation). This new subsection includes information on locating available functions from the foundation library, binding to those functions and using these bindings from within a LiveCode Builder module.
A release note has been added, with the following line: Add more FFI examples to the Extending LiveCode Guide
@livecodeali do you think this can be rebased against |
@livecodepanos Yes, I don't see why not |
* Binding to the [CFDataGetBytePtr function](https://developer.apple.com/documentation/corefoundation/1543330-cfdatagetbyteptr?language=objc) within Apple's C-based Carbon framework for macOS: | ||
|
||
foreign handler C_CFDataGetBytePtr(in theData as ObjcId) returns Pointer \ | ||
binds to "c:Carbon.framework>CFDataGetBytePtr" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrewferguson CFDataGetBytePtr
is in CoreFoundation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is (to me at least) odd:
The binding to CFDataGetBytePtr is successful and appears to work as expected when the framework is one of:
Carbon, Foundation, CoreFoundation, CoreGraphics, CoreAudio, CoreVideo,...
I have a feeling that maybe LiveCode is just ignoring the framework name and binding to the correct function. It doesn't, however, bind if the specified framework doesn't exist (e.g: HappyTime.framework gives "unable to load foreign library").
Is this expected behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect it works for all of those because all of those frameworks depend on CoreFoundation (and thus you can import the symbol from it, because it has already imported that symbol); OR, it is because where various things have actually lived in the OS has changed through the mac versions (mac has the notion of 'Umbrella' frameworks, which is a framework which encompasses many others) and so they are all seen as 'essentially the same thing' at the OS level.
In the binding code in the engine, we always dlopen() the specified library, and then dlsym from that handle (as far as I'm aware) - which is why it fails if you pass a library which doesn't actually exist.
|
||
unsafe handler StringFromUTF8Data(in pData as Data) returns String | ||
variable tDecoded as String | ||
MCStringDecode(pData, 4, false, tDecoded) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good to declare a constant here so 4 doesn't seem like such a magic number
|
||
* the name of the function in the LCB declaration must exactly match the name of the function | ||
in the foundation library | ||
* the binding string is simply `<builtin>`, with no class or function name specified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worthwhile explaining that any of <builtin>
, MCStringDecode
and c:MCStringDecode
will work as a binding string here? Perhaps it's worth saying that if you want to name your foreign handler something other than the name of the function then you can use a binding string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add in a note about c:MCStringDecode
. I don't think it is necessary to explain MCStringDecode
because this is something that is not specific to binding to the foundation library and should instead be explained with the general format of C binding strings (probably in the language reference).
I've updated the C FFI section of the "Extending LiveCode" guide to include a couple more examples of wrapping C functions (including an example of wrapping one of Apple's C-based APIs) and a guide to utilizing the already-written C/C++ functions that are available through LiveCode's foundation library (libfoundation).