C/C++ External dynamic library linkage -- example project?

  1. ‹ Older
  2. 2 years ago

    Stephen G

    1 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P -- My project is already TEXT, so I guess I will try the method you describe in #4.

    I just thought there was a way to define a dummy function where the definitions would be global / public, so they could be tweaked free-form in the code.

    I looked at editing the TEXT, and each definition might look something like this:

    	#tag ExternalMethod, Flags = &h0, Description = 47657473206120537472696E672066726F6D2074686520636C617373
    		Soft Declare Function getACStringFromClass Lib "libTestLibForXojo.dylib" (Ptr) As CString
    	#tag EndExternalMethod

    That "Description" must be some sort of GUID? So not the friendliest interface for using a text editor...

    During development / debugging, can the dylib (MacOS) be located in the same folder as the .xojo_project TEXT file? Will Xojo automatically search for it there? And when BUILDING -- how does Xojo copy it to the app package /Contents/Frameworks folder?

  3. Norman P

    2 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    Just skip the description entirely

    	#tag ExternalMethod, Flags = &h0
    		Soft Declare Function getACStringFromClass Lib "libTestLibForXojo.dylib" (Ptr) As CString
    	#tag EndExternalMethod

    You can make sure the dylib ends up in Frameworks by adding a "Copy File Step" that is AFTER the build step in the Build Settings > MacOS

  4. Stephen G

    2 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    You can make sure the dylib ends up in Frameworks by adding a "Copy File Step" that is AFTER the build step in the Build Settings > MacOS

    @Norman P -- excellent! And for non-build running / debugging -- where should I place the dylib so the Project automatically can find it using the same soft declare specification (i.e. without my having to specify a path in the ExternalMethod tag?

    Also -- can I put multiple declares inside the same #tag ExternalMethod, or do they each have to have their own?

  5. Norman P

    2 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...
    Edited 2 years ago

    do nothing and leave the copy file step to run in both debug & run

    but you probably WILL want to specify a path as they can cause issues if you dont
    if you plan to deploy via the app store they'll need to be in "the right place"
    I'll find the right one for macOS
    it will be something like "@executable_path/../Frameworks/<your dylib name here>"

    externals are one per tag

  6. Stephen G

    2 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P --

    I think I've got it working (thanks to all the help!)

    The copy step works for a BUILT version -- it puts the desired dylib in the built.app/Contents/Frameworks location -- and this executes perfectly!

    The first time I tried to "Run" the project using the debugger, the ExternalMethod couldn't be found during execution, and generated an exception. Subsequently, after I re-pressed the Build button, making no change to the copy script, now everything worked using "Run" button -- not sure why. But I think I can press forward at this point.

    For IOS (haven't experimented there yet), I assume I'll need to do a static link to the .dylib? Will the same ExternalMethod declarations continue to permit calls from an IOS project?

  7. Norman P

    2 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    You should be able to do soft declares on iOS the same as macOS

    The copyFile step should put things in the right spots for build & debug runs if you dragged the dylib in there & set it to copy to "Frameworks"
    On iOS and macOS this varies in the actual file location when the step is performed (but you dont have to really sweat that too much)
    On macOS it should land in the Bundle > Contents > Frameworks
    On iOS they dont build bundles the same, they're flatter. So it may just end up in the root level of the package (I forget to be honest)

  8. Stephen G

    2 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington
    Edited 2 years ago

    @Norman P --

    I think I was a little premature in my testing --

    When I went to add all of the soft declares as External Methods in a separate Module, my actual runtime calls couldn't locate them generated a FunctionNotFound exception. This time I was careful to make sure I was only building a 64-bit dylib, and a 64-bit Xojo executable. The dylib IS being copied into the built app's Content/Frameworks folder.

    Perhaps there's an Xcode build pref that still needs to be set? ALTHOUGH -- worked perfect when done through soft declare and path was provided...

    Do External Method names need to be prefixed with the name of the Module, if that External Method is declared as "Global"?

  9. Stephen G

    2 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P -- OH, you are going to be AMAZED by this...

    As a TEST -- I uncommented the FIRST of four soft declares I had made during my initial testing (I had commented them out when I was testing adding all four External Methods to a separate Module)

    When I did that, then there was NO PROBLEM calling the other three External Methods -- either when RUNNING or BUILDING/Double-Clicking the built app.

    It's like my first soft declare (with an EXPLICIT absolute path) caused the dylib to be found and loaded, so there was no longer any kind of dynamic binding issue during execution.

    If I commented out that soft declare, none of the External Methods could be found now -- although there was absolutely no link warning about an undefined symbol.

    Does that theory make sense?

  10. Andrew L

    2 Nov 2017 San Francisco, CA, USA

    Did you click the "soft" check box on the external method editor?

  11. Stephen G

    3 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Andrew Lambert -- Yes, definitely set the "soft" check box. I think this has to do with WHERE Xojo is expecting to find the dylib -- OR the crazy dylib settings like @rpath that need to be set when linking the dylib.

  12. Norman P

    3 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    if the dylib is in this location "@executable_path/../Frameworks/<your dylib name here>" as a result of the copy files step then things should just work
    however you may need a constant with different values for macOS, Windows, iOS and Linux since they will be in different spot (particularly the iOS one)
    So dont use the "default" value of a string constant and add several different values with their language set to ANY but each having a different OS (macOS Cocoa, iOS, Windows and Linux) so there are 4 different entries - and the right value for each
    At compile time the correct one will be selected& used to compile your app

  13. Stephen G

    3 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P --

    I'm just trying to get macOS working first. And now I THINK I have:

    The name of the lib's name in the External Method definition UI needed to be set to:

    @executable_path/../Frameworks/libTestLibForXojo.dylib

    ...which is what you said:

    if the dylib is in this location "@executable_path/../Frameworks/<your dylib name here>" as a result of the copy files step then things should just work

    But I though you meant if the dylib was IN THAT LOCATION -- which it already was. But I hadn't set the Lib name in the UI to that EXACT syntax.

    So it look good now!

    Thank you! (and everyone else)!

    ..now on to IOS / Windows tests....

  14. Norman P

    3 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...
    Edited 2 years ago

    ah yeah - the external needs to have the location as it will be at runtime since these are dynamically linked
    the link loader will find them at runtime based on that path when your app runs
    at compile time it doesnt matter where the actual dylib is since they are just going to be copied into your built app by the copy file step into the location you specified

  15. Stephen G

    3 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P -- OK -- so you are agreeing with what we posted above:

    1) Name of the lib's name in the External Method definition UI needs to be set to: @executable_path/../Frameworks/<myDylibName.dylib>

    2) Must add a Build Step > Copy Files to copy the above dylib to the Framework Folder (in the App package). This will work for BOTH "run with Debugger" or launching the built executable App.

    3) In Xcode, the Linking Setting "Dynamic Library Install Name" should be just the name of the built dynamic library <myDylibName.dylib>, which is also the Xcode default of $(EXECUTABLE_PATH).

    4) A CONSTANT may be created to handle different dylib paths for multiple platforms. For example, #App.kDylibLocation can be defined for platform "OS X Cocoa" for "English" as "@executable_path/../Frameworks/<myDylibName.dylib>", but for "IOS" "English", it would need to be a different path (do you know what that path might need to be?)

    How's that?

  16. Norman P

    3 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...
    Edited 2 years ago

    That seems about right

    the iOS path seems like it should be @executable_path/Frameworks/<myDylibName.dylib>
    note the missing ..

    and you probably dont need these to be set for "english"
    any language should be fine

  17. Stephen G

    3 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington

    @Norman P -- on the subject of dynamic libraries and IOS --

    I'm running into the "FunctionNotFoundException" during the iPhone simulator execution when trying to soft declare against a C-API function in the dylib I generated for IOS 9.2 (arm7, arm64).

    I DO the build_step to copy the dylib to the Frameworks folder.

    Do I need to build the dylib as a "Framework" for this to work on IOS?

  18. Norman P

    3 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...

    the sims are x86 or x86_64 :)

  19. Stephen G

    3 Nov 2017 Pre-Release Testers, Xojo Pro Ellensburg, Washington
    Edited 2 years ago

    @Norman P -- OHHHHH -- so for the IOS simulator, i.e. Xojo's "RUN and DEBUG" option, I should use the same old dylib as MacOS? Not code built for arm7/arm64? Is that true of BUILD, too?

    AND TO BE CLEAR: are you saying I should build a .dylib in Xcode against the IOS SDK but with the x86 / x86_64 architecture? Or simply USE the same Xcode-generated x86 / x86_64 dylib I build for MacOS? NOTE: in either case, these are pure C++ code libraries -- completely cross-platform -- no cocoa (or carbon) whatsoever.

    At what point do I build an arm64 dylib for deploying on real IOS hardware, and can Xojo do a build integrating that dylib in a way acceptable to the Mac App store (unlike posts on this forum from 16 months ago, which stated the Mac App store would NOT accept a dylib)?

    Your documentation states that the simulator only (presently) runs a 32-bit app. Has that changed? Obviously, 32-bit is now history on IOS.

  20. Norman P

    4 Nov 2017 Xojo Inc, Pre-Release Testers, Xojo Pro Seeking work. npalardy@great-w...
    Edited 2 years ago

    @StephenGreenfield @Norman P -- OHHHHH -- so for the IOS simulator, i.e. Xojo's "RUN and DEBUG" option, I should use the same old dylib as MacOS? Not code built for arm7/arm64? Is that true of BUILD, too?

    I'd used one built for iOS if there are sdk dependencies. if not the macOS x86 should be OK
    The simulators run x86 code so they are only simulating what you will experience on da real device
    They do not run arm or arm7 code
    For deployment you should use arm / armv7 code

    @StephenGreenfield AND TO BE CLEAR: are you saying I should build a .dylib in Xcode against the IOS SDK but with the x86 / x86_64 architecture? Or simply USE the same Xcode-generated x86 / x86_64 dylib I build for MacOS? NOTE: in either case, these are pure C++ code libraries -- completely cross-platform -- no cocoa (or carbon) whatsoever.

    I'd expect that you could use the same dylib as macOS as I expect, but honestly dont know for sure, that they both support the same C++ runtimes

    @StephenGreenfield At what point do I build an arm64 dylib for deploying on real IOS hardware, and can Xojo do a build integrating that dylib in a way acceptable to the Mac App store (unlike posts on this forum from 16 months ago, which stated the Mac App store would NOT accept a dylib)?

    You cannot statically link in a dylib - in Xojo or any other tool
    As for submission to the app store I am not 100% sure if they will or will not accept apps with dylibs in the Frameworks dir of the app package

    @StephenGreenfield Your documentation states that the simulator only (presently) runs a 32-bit app. Has that changed? Obviously, 32-bit is now history on IOS.

    You can actually debug in 32 bit (set break points etc and step through code)
    You can RUN in 64 bit but debugging is not possible as it is for 32 bit

    When you build we always, currently, build a universal app which as 32 and 64 bit code

  21. Christian S

    4 Nov 2017 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    when you build for simulator, Xcode will automatically build x86/x64 for you.

  22. Newer ›

or Sign Up to reply!