Convert 4D Plugin (in C) to work with XoJo

Hi All,

I have been a 4D Developer for decades. I have a cross-platform standalone application that relies upon a 4D plugin written in ‘C’. {For reasons beyond this thread… the app needs a new home for MacOS and Windows}

Before I can fully commit to XoJo I need to make sure that all the tools I will need are available.

  1. I use the Swiss Ephemeris (SE) a ‘C’ software toolbox (high-precision ephemeris calculation engine) that provides astronomical data. Plus my own ‘C’ code uses SE. This is what is contained within the 4D plugin. I have it set for Xcode and Visual Studio. So I can recreate the plugin on demand.

  2. Access to vector graphics to create the drawings and reports I need.

  3. Keeping my UI the same as it is (or very close).

So…

The first step is converting the 4D plugin code into a format that allows it to be compiled as XoJo plugin. Using Xcode on Mac and Visual Studio on Windows.

It has been recommended that set the code up so that calling into the library via a declare would be easier. But what does this mean? What format must the code be in? Is it a DyLib on Mac and DLL on windows?

I need help seeing how to structure this in Xcode and Visual Studio.

I may need a mentor.

Anyone?

Appreciate,

John…

Welcome to Xojo! Sounds like you got a new price list for 4D.

You can decide:

  1. Plugin
  2. Declare

For plugin, you may just take the plugin SDK from the Xojo Extra folder after installation and see if you can build it with Xcode/Visual Studio. Then add function by function as needed.

For declares, you make a shared library (Dylib/DLL) with whatever tool you like, add your functions, export them and then write a matching declaration in Xojo to run them.
Xojo includes example projects for declares to learn how they work.

As you may know from moving in the real world, every moving to a new place gives a chance to check your stuff. You may find that you don’t need to carry over everything. Some things you stopped using. Others are already built-in to Xojo. And some things may be available already as add-on, so you don’t need to do it yourself.

2 Likes

Hi Christian,

Thanks for responding!

“shared library, Dylib, DLL” these are presently abstract terms to my mind. Never had to deal with them. I am also a visual learner, so seeing is an important part of figuring things out.

For plugin, you may just take the plugin SDK from the Xojo Extra folder after installation and see if you can build it with Xcode/Visual Studio

That makes sense as a first step.

Outside of XoJo’s examples, are there any others that can point me in the direction of how I need to configure these “plugins”?

Are you available, at a reasonable hourly rate, for mentoring?

Thanks,
John…

Well, if you got the example running and you have questions, please post them in the forum.

And maybe I can offer some help.

Hi Christian,

Using XCode I built ‘VariantTester.dylib’.

So, ok, I can do that. But what am I trying to build? a static library or a dynamic one?

How does XoJo “know” how to read from exposed functions?

Here’s is a screen shot showing my 4D plugin setup and the VariantTester setup.

Appreciate any direction.

John…

You build the plugin example?
Great, you can drop the dylib in the Xojo Plugins folder and start Xojo.

You may also want to read the documentation in the plugin SDK about how to build a plugin archive.

And your dylib may include info.plist with version information.

Hi John,

Making a few assumptions here.
The package available at https://github.com/aloistr/swisseph contains swisseph-master\windows\sweph.zip.
Unpacking this (in place) reveals swisseph-master\windows\sweph\bin\swedll64.dll
This can be used on Windows by Xojo via declares.
The assumption is that this is the correct dll you want to be using!
There is some documentation at: Downloading Swiss Ephemeris Code and Data - Astrodienst
I have put together a very (very!) simple Xojo project that uses this dll, unfortunately it cannot be posted here.
Assuming this is the correct dll, you could contact Customer Service via Xojo: Contact Xojo and it should be possible to send the project to you.

Apparently I can post a sample project here :slight_smile:
Here goes:
SE_Demo.zip (451.7 KB)

1 Like

Hi Robin,

The assumption is that this is the correct dll you want to be using!

It’s not complete as I have added my own code in addition to the swisseph. But it’s a great start as I need to get my mind around how the plugin needs to be setup so that XoJo Declares can see it.

I really appreciate the example and I will setup up a Windows XoJo (I’ve been testing with Mac) later today.

So am I correct then in assuming that I will need to create a Dynamic Library on the Mac? Not a static library?

Thank you!
John…

Hi Christian,

Yes I reading the docs for plugin SDK and XoJo Declare info and…

dylib may include info.plist…

OK, so on the Mac I am creating a dynamic library?

Thank again,
John…

Hi John,
I don’t know much about the Mac side of things.
Will try and find someone to help; it might not be possible though.
Very very busy and the holidays are coming up.

Hi Robin,

I’m pretty sure - after reading through every google search article I could find - that I needed to create a dynamic library.

A Windows DLL and a Mac DyLib must be conceptually, at least, similar.

I think I figured out what I need to do to create a Dylib on the Mac.

I’ll see how far I get.

Appreciate the support,
John…

Well, a plugin is a shared library with a special entry point.
So dylib for macOS and dll for Windows.
The plugins itself are zip archives. Feel free to unpack one to lookup the structure.

Hi Christian,

Yea I think I understand that. But I and another developer created this plugin many years ago. So I’ve forgotten all that I learned then.

While searching in google, I need to use the exact correct words or else, I can spend a lot of time going down an unproductive rabbit hole. Like most of the last couple of days.

Thanks for confirming!!!

John…

Hi Robin,

I have setup XoJo on Windows 11 home. I have copied the demo and ran it.

But I see no values being displayed after the Test button is clicked.

When I trace the ‘btnTest’ script none of these variables have values.

Is that what I am supposed to experience at this point?

Note: when I show about and plugins the ‘swedll.dll’ doesn’t show up in he list. Is this also correct?
If so how would I know it’s loaded correctly?

Hope these are easy to answer.

Thanks,
John

So to be clear, a Xojo plugin does not require Declare statements. It is a special form of library that Xojo knows how to talk to and get information on the classes, methods, etc that the plugin provides.

A raw DLL / dylib on the other hand, is just a series of functions, you use declares to tell Xojo what those functions are and how to use them. C++ methods have to be declared as “extern C” to that C++ type munging doesn’t cause oddly named functions.

Hi Ian,

I was directed by Geoff to code them so they were accessible via declares. He said that would be easier.

The screenshot image above is all C code - although we did use extensions for C++ for using the Swill Ephemeris API. In a 4D plugin I didn’t need to use ‘extern C’. But having a routine exposed as external make sense.

For a 4D plugin I started with two files the header and the code.

Header name Plugin.h
Code name Plugin.cpp

In the header we set up an enum whihc told the plugin the name and order of the commands. Like this:

enum {

eCMD_swe_calc_ut_4d = 1,
eCMD_swe_calc_ut_4d = 1,
eCMD_swe_close_4d,|

};

Followed by calls:

void InitPlugin();
void DeinitPlugin();

void swe_calc_ut_4d( PA_PluginParameters params );
void swe_close_4d( PA_PluginParameters params );

and so on…

In the code file it looked like this:

bool isRegistered = false;

void PluginMain( PA_long32 selector, PA_PluginParameters params )

{

if( !isRegistered && selector > 0 && selector != eCMD_swe_register_4d )

{

printf( “Please register Swiss Ephemeris Plugin first.\n” );

return ;

}

switch( selector )

{

case kInitPlugin :

InitPlugin();

break ;

case kDeinitPlugin :

DeinitPlugin();

break ;

// — ELM Planet Calculations

case eCMD_swe_calc_ut_4d :

// Modified version of swe_calc

swe_calc_ut_4d( params );

break ;

case eCMD_swe_close_4d :

// releases most resources used by the Swiss Ephemeris

swe_close_4d( params );

break ;

And so on…

We also need a manifest file like this;

{
“name”: “Swiss Ephemeris Plugin”,
“id”: 17000,
“commands”: [
{
“theme”: “ELM Calculations”,
“syntax”: “swe_calc_ut_4d(&8;&L;&L;&Y;&T):L”
},
{
“theme”: “ELM Calculations”,
“syntax”: “swe_close_4d”
}
… and so on
]
}

So I am trying to get from this kind of organization to what is required by XoJo for both MacOS and Windows.

Does this make sense?

I am hoping that I can pretty much reuse the code from the 4D Plugin and update as XoJo requires.

This is why I am asking about such basic things as DyLib, DLL, etc. Never had to deal with them until now.

Any further guidance would be welcomed!

Appreciate,
John…

If you are just going to use Declares then none of that is required for Xojo. You simply need a DLL with the functions declared as “extern” (or “extern C” if using C++). Once you have that you build matching declare statements in Xojo.

For example if you have a C function called multiply that takes two doubles and returns a double of them multiplied together. The Declare would be as follows:

// excuse my very rusty C code
extern double multiply( double a, double b ) {
   return a * b;
}
Declare function multiply Lib "YouDLL/Dylib" (a as double, b as double) as double

That declare teaches Xojo everything it need to know about that function. ie The Name (multiply) the lib to find it in (“YouDLL/Dylib”), that it takes two parameters a and b that are both doubles and that it returns a value which is also a double.

You can make Windows and macOS versions of that call as follows:

#if TargetMacOS
   Declare function multiply Lib "dylibname" (a as double, b as double) as double
#elseif TargetWindows
   Declare function multiply Lib "windows.dll name" (a as double, b as double) as double
#end
// call it in the same way for both platforms
var avalue = 100
var bvalue = 2903
var result
result = multiply( avalue, bvalue )

The principal goes for pretty much any more complex example. You match the C function to a declare that teaches Xojo to call the function.

Hi John,
When running the demo project make sure you have the Messages panel open.
It’s the right-most button of the three located on the bottom edge of the IDE window:
image

Video:
SE_Demo.zip (451.7 KB)

Hi Ian,

Thank you.

I woke very early this morning realizing that I needed to step back and learn how to create a DLL for Windows and a dyLib for the MacOS.

Thanks for sharing these code samples, as they are helpful.

I need to give myself time to absorb this new learning.

Appreciate,
John…