Make class wrapped DotNet dll optional

I am currently creating many integrations between Clarion 11 and DotNet dlls using NativeAoT - now for a specific integration I want to make it optional, so only enable it when the DLL is present in the application’s directory - but I noticed when the DLL is not there the program won’t start - even when I Guard the class uses against this by checking if it exists before trying to call it.

So, my question, is this even possible? Because if it is, I could create a plugin-like structure this way (of course the Plugins will be pre-defined in the application)

Are you currently linking the import .LIB for the NativeAOT DLL into your Clarion application?

If so, I think that’s why your guard doesn’t help. With the normal DLL(1) declaration/import library, Windows needs to resolve the DLL while loading the EXE, before any of your Clarion code gets a chance to check whether the DLL exists.

Clarion does have support for doing exactly what you want using DLL(_fp_). Instead of linking the optional DLL through its import library, you load it yourself with LoadLibrary, resolve the exported functions with GetProcAddress, and put those addresses into the variables used by the DLL(_fp_) declarations.

The basic pattern is:

MODULE('MyPlugin')
  PluginFunction(LONG pValue),LONG,PASCAL,RAW,DLL(_fp_)
END

hPlugin          UNSIGNED
fpPluginFunction UNSIGNED,NAME('PluginFunction')

Then load and resolve it:

MODULE('')
  LoadLibrary(*CSTRING),LONG,PASCAL,RAW,NAME('LoadLibraryA'),DLL(1)
  GetProcAddress(ULONG,*CSTRING),ULONG,PASCAL,RAW,NAME('GetProcAddress'),DLL(1)
  FreeLibrary(ULONG),LONG,PASCAL,PROC,NAME('FreeLibrary'),DLL(1)
END

and roughly:

DllName  CSTRING(260)
ProcName CSTRING(100)

DllName = 'MyPlugin.dll'
hPlugin = LoadLibrary(DllName)

IF hPlugin
  ProcName = 'PluginFunction'
  fpPluginFunction = GetProcAddress(hPlugin,ProcName)
END

Once fpPluginFunction contains the exported function address, you call it normally:

IF fpPluginFunction
  Result = PluginFunction(SomeValue)
END

Clarion routes the call through the function pointer because the NAME() on the pointer variable matches the link name of the DLL(_fp_) prototype.

StringTheory uses this sort of pattern for zlibwapi.dll, so there are existing Clarion examples to work from.

That should give you the plugin-like arrangement you’re after: the main EXE has no load-time dependency on the optional NativeAOT DLL, so it can start without it. If the DLL is present you LoadLibrary it and resolve the exports; if it isn’t, you simply leave that integration disabled.

Obviously you’d want to resolve/check all the exports required by a plugin before considering that plugin successfully loaded.