Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

[[Bugfix 21530]] Add more FFI examples to the Extending LiveCode Guide #1993

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

andrewferguson
Copy link

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).

…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.
@andrewferguson andrewferguson changed the base branch from develop-9.0 to develop August 27, 2018 15:34
A release note has been added, with the following line:

Add more FFI examples to the Extending LiveCode Guide
@livecodepanos
Copy link
Contributor

@livecodeali do you think this can be rebased against develop-9.0? It would be good to have it in LC 9.0.2 rc-1 too

@livecodeali
Copy link
Member

@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"
Copy link
Member

@montegoulding montegoulding Aug 28, 2018

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

Copy link
Author

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?

Copy link
Contributor

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)
Copy link
Member

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
Copy link
Member

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.

Copy link
Author

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).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants