Dylib path issues

I’ve started to learn about writing custom dylib plugins by using the StructAndEnum example from the Plugins SDK, but I’ve run into an issue with the plugin path not being found when placing the dylib within the app bundle.

Using Xcode 11.3, I was able to compile a 64-bit plugin with an extra test function returning a Single:
static float HelloWorldTest() { return 42.0; }
Hooking it into REALmethodDefinition and compiling it, I placed the plugin directly into Xojo 2020r2’s Plugins folder (per the SDK doc’s suggestion for testing) and launched the IDE: works fine when call
Var answer As Single = HelloWorldTest()
and my hard-coded value in the dylib returns as expected. Also, the provided example Xojo code also works just fine.

However, I’d like to be able to put the dylib into the built app with a Copy Files build step. Doing this breaks my test and the example code.

The docs don’t seem to mention how to handle the dylib outside, and my own attempts to Soft Declare to it have fallen flat, ie:
Soft Declare Function HelloWorldTest Lib “@executable/…/Frameworks/StructAndEnum.dylib” () As Single
And I’m not even sure how to go about accessing the example’s custom structs and enums.

I’m assuming it’s a path issue, but multiple variations on the Lib path still gets me a framework not found error.

I’ve done a deep dive into the forums but haven’t found a solution that I’ve been able to get working. I’m hoping I’m missing something obvious as I’ve been hammering away at it for the past few days.

I believe it should be “@executable_path” not “@executable” for your declare

I mistyped in my original post. I did use “@executable_path

I realized hit send before finishing my sentence. Meant to say
I did use “@executable_path” but it still did not work for me, so I’m still stuck.

Can you post the actual code from your app in a code block? You also have 3 dots instead of 2 which might just be since you typed it into the forum? An example of making your own dylib and calling it can be found here: https://www.great-white-software.com/blog/2020/04/14/creating-a-rust-dylib-we-can-call-from-xojo/

Why do you use declares when you build a plugin?

A plugin doesn’t need declares to run.

@Jason King - Yeah, because I typed it manually it I probably added a third dot by accident.

In Window1.Open of a new app, I have the following lines (this is the entire app, no code anywhere else)

Soft Declare Function HelloWorldTest Lib "@executable_path/../Frameworks/StructAndEnum.dylib" () As Single
Var a As Single = HelloWorldTest()

I have a Copy Files build step that has a destination of Frameworks Folder.

I’ve modified the StructAndEnum.cpp by adding

static float HelloWorldTest()
{
    return 42.0;
}

And have extended the included testMethods array thusly:

static REALmethodDefinition testMethods[] = {
	{ (REALproc)TestStructMethod, REALnoImplementation, "TestStructMethod( ByRef test as TestStructure )", REALconsoleSafe | REALScopeGlobal },
	{ (REALproc)TestStructureArrayMethod, REALnoImplementation, "TestStructArrayMethod( test() as TestStructure )", REALconsoleSafe | REALScopeGlobal },
    { (REALproc)HelloWorldTest, REALnoImplementation, "HelloWorldTest() as Single", REALconsoleSafe | REALScopeGlobal },
};

That’s the entirety of my changes to the example.

@Christian Schmitz - Because I’ve used another 3rd party dylib before in a similar manner, so I thought it would run similarly. This is my first foray into writing my own dylibs, so I’m learning lots.

you have three periods, when it should be two.

@Sam Rowlands - I’ve amended my original post where I mistyped the number of periods. Even with two, it fails for me.

I’ve modified the path multiple times, dotting the path up and down to see if I could hone in on it. I’ve tried a full native path to no avail. I even double-checked with a FolderItem and it says it exists, even copying the file to Terminal for a path to cut and paste. I’m stumped.

I’ll confess, it has been a long long time since I created a Xojo plugin.

I think you’re going to need someone from Xojo, like @Greg_O_Lone or @William_Yu to help here.

I’m with Christian, why not treat this as a Plugin and move it into your Plugins folder so you can reference it in your code? Also, your HelloWorldTest function does not appear to be exported (considering it’s a static function) so even if you got the right declare it would not find that function anyway.

In case this is really important to you, we do look next to the actual executable (i.e. not the bundle directory but the actual executable found in the Contents/MacOS directory). So you could move your dylib in there and reference it using a simple

Declare Sub MyFunctunion Lib “StructAndEnum.dylib” ()

@William Yu - I must be doing something wrong: I can’t even get your suggestion to work.

What is working in my case is to keep the dylib in Xojo’s Plugin folder.

Upon compile, I see that Xojo automatically places the dylib in Contents/Frameworks and my HelloWorldTest function works. I was afraid that I would still need to bundle the dylib separately after compile, so I’m relieved that this isn’t the case.

Even so, I still can’t figure out why I can’t Declare to it given that the Copy Files build step placed the dylib in the exact same location.

I doubt you’ll get anything to actually “work” in your Declare example since the only exported function in your plugin is likely the one that we explicitly export, and that is our main entry point. When you’re working with our Plugins SDK the functions that you reference are not strictly exported (you might want to read up on C/C++ docs to understand this).

Declare Sub REALPluginMain Lib “StructAndEnum.dylib” ()

Right, we automatically copy all the necessary plugins into your app.

We handle things a little differently with Declares as opposed to when loading up Plugins that were compiled into your app.

@William Yu - Thanks for the tips. I’m admittedly very rusty on C.

I know what I did wrong, and both Christian’s and William’s replies were the clue: I have wrongly equated Xojo’s plugins with dylibs.

I decided to find a tutorial on Xcode dylib building and followed it. Now my HelloWorldTest Declare works. I was definitely overthinking things!

3 Likes