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

String containing printable characters = UTF8
String containing other values = binary data

String can hold both. Text can only hold “printable” or “normal” text, not arbitrary binary values.

String MIGHT hold bytes that represent “text” in any encoding - there’s a long list we support.
Or be just a “bucket of bytes”

TEXT is ALWAYS textual data - never a “bucket of bytes”

OK – thanks Tim & Norman – that’s pretty clear now.

So, at the end of the day – if I am absolutely returning “printable” UTF-8 text, and storing it into a Text object, is there any advantage to the MutableMemoryBlock / MemoryBlock versus the toCString() fromCString() Text member / class static functions?

The more I read this thread the more I’m surprised no one has said “take your existing C/C++ code and compile a plugin that uses it”
Quite honestly that gives you the ability to do some things that you wont get from C/C++ (like creating Strings - not sure Text are in the plugin SDK) and accessing the innards of types via a well defined API

Then you can just write Xojo code that uses your plugin much more simply than you can via a large body of declares

@Norman Palardy – I was wondering about plug-ins, too. Maybe some of the plug-in developers, like @Christian Schmitz can give an opinion on the advantages and disadvantages of plug-ins vs dylib/dll via soft declare.

Are plug-ins used consistently across the desktop platforms vs IOS, web, and (eventually) Android?

Is there an added inefficiency making a call into a plug-in, vs a call into a dylib / dll?

With my C++ dylib/dll, the intention is to make the same C-API available to a number of different development environments, for example Python / Java / Javascript. So having one clear C-API across all platforms may outweigh any advantages built Xojo apps get from accessing that API via plug-in.

I did suggest that at the very beginning:

[quote=354225:@Eli Ott]You have two options:

Plugins:
Develop the API in C/C++ and C/Objective-C so that in Xojo you do not need any declares into dynamic libraries. See Plugins-SDK .

Declares:
[…]
[/quote]

From a user perspective I find declares a pain. A plugin is much preferred. You might want to talk to the Chilkat guy who is already doing what you want. His excellent plugin is cross-platform and cross-language. Which ends up being less OO than I might want and not really Mac-like. But the plugin does it’s job.

A plugin is something very tied to the Xojo framework.
If you are developing only for the Xojo ecosystem because you are selling plugins or giving plugin to other Xojo developers this can be a viable solution.
For a developer the cost to create AND maintain a plugin is much higher than the one required to create and maintain a dll and a module containing only declares.

A plugin is a solution only if:

  • you have the source to create the final dll/plugin
  • you are using the dll only in Xojo projects
  • you have completely debugged the dll code before the conversion from a pure dll to a Xojo plugin
  • you are willing to maintain the plugin as Xojo evolve
  • having the dll implementing the plugin included in the program library folder isn’t a problem

The final result is that you must know how to create a dll to create a plugin and a plugin is useful only if you are developing dll for other developers.

This will probably change when Xojo will deliver what required to develop plugins using only Xojo code.

The question of this thread is not about plugins/declares in general, but about a wrapper for a self-written C++ library, which Stephen wants to use in Xojo.

The plugin can define a Xojo class, so it would be a very comfortable wrapper.
Better maybe than a bunch of declares.

[quote=354225:@Eli Ott]Plugins:
Develop the API in C/C++ and C/Objective-C so that in Xojo you do not need any declares into dynamic libraries. See Plugins-SDK .[/quote]

[quote=356801:@Christian Schmitz]The plugin can define a Xojo class, so it would be a very comfortable wrapper.
Better maybe than a bunch of declares.[/quote]

Ah - no plugins on iOS so scrap that idea

@Norman Palardy – right – no plugins on IOS but of course on IOS I can still link to my library? As a static link, rather than a dynamic dylib?

I ask this in another posting, but if I wanted to put all my soft declares into ONE Xojo source code module, how do I add that? Most of the things that can be “added” to the project have their own editors. Is there a way to add a purely free-form source code module that isn’t associated with a particular class?

No you can link to a dylib - what you cant use is a Xojo plugin since they dont exist for iOS
You may have to call into it using a path that looks a little odd but it can be done

[quote=356891:@Stephen Greenfield]
I ask this in another posting, but if I wanted to put all my soft declares into ONE Xojo source code module, how do I add that? Most of the things that can be “added” to the project have their own editors. Is there a way to add a purely free-form source code module that isn’t associated with a particular class?[/quote]

This assumes that a module etc is “just one big pile of text you can just edit” which it isn’t

IF you want to do it

  1. create a module
  2. add ONE external method to it
  3. save you entire project as a TEXT project
  4. you can then edit that module with a plain text editor BUT you MUST make sure you adhere to the form for each external method that is in that file already as if you dont the IDE will not be able to reload that item in your project

@Norman Palardy – 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?

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

@Norman Palardy – 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?

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/”

externals are one per tag

@Norman Palardy –

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?

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)