Loading Chilkat library in PureBasic
When using OpenLibrary()
in PureBasic to load a shared library (DLL on Windows, .so
on Linux, or .dylib
on macOS), the library must be located in a directory where the OS’s dynamic linker can find it.
Each Chilkat .pb file, such as CkCrypt2.pb, contains the following fragment for loading the Chilkat shared library:
CompilerSelect #PB_Compiler_OS CompilerCase #PB_OS_Windows CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 CkCacheLibId.i = OpenLibrary(#PB_Any, "chilkatPb32.dll") CompilerElse CkCacheLibId.i = OpenLibrary(#PB_Any, "chilkatPb.dll") CompilerEndIf CompilerCase #PB_OS_MacOS CompilerIf #PB_Compiler_Processor = #PB_Processor_arm64 CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPbM1.dylib") CompilerElse CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPb.dylib") CompilerEndIf CompilerCase #PB_OS_Linux ; Note: The full path of the .so shared library will be required when running from a compiled executable on Linux. ; See https://www.purebasic.fr/english/viewtopic.php?t=79882 CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPb32.so") CompilerElseIf #PB_Compiler_Processor = #PB_Processor_arm32 CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPbArm32.so") CompilerElseIf #PB_Compiler_Processor = #PB_Processor_arm64 CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPbArm64.so") CompilerElse CkCacheLibId.i = OpenLibrary(#PB_Any, "libchilkatPb.so") CompilerEndIf CompilerEndSelect
If OpenLibrary fails
, your application will crash with the error: Invalid memory access. (write error at address 0)
Here’s a breakdown by platform:
Windows (.dll
)
OpenLibrary()
will search in this order:
- Full path if you pass it.
OpenLibrary(0, "C:\libs\example.dll")
- If only a filename is given:
- The current working directory
- The directory of the executable
- The system folders:
C:\Windows\System32
C:\Windows\SysWOW64
(for 32-bit apps on 64-bit systems)- Folders in the system PATH environment variable
Windows Tips:
- You can temporarily add a path using:
SetCurrentDirectory("C:\MyLibs\") OpenLibrary(0, "example.dll")
Linux (.so
)
OpenLibrary()
uses the system dynamic linker. The .so
file must be:
- In a directory listed in the environment variable
LD_LIBRARY_PATH
, or - In a standard system location like:
/usr/lib
/usr/local/lib
/lib
- In the current working directory (in some cases)
Linux Tips:
- Set
LD_LIBRARY_PATH
at runtime:export LD_LIBRARY_PATH=/home/user/mylibs:$LD_LIBRARY_PATH ./myprogram
- Or give the full path:
OpenLibrary(0, "/home/user/mylibs/libexample.so")
macOS (.dylib
)
macOS uses DYLD_LIBRARY_PATH
and search paths similar to Linux.
OpenLibrary()
will search:
- Full path, if provided
- Environment variable
DYLD_LIBRARY_PATH
- System folders:
/usr/lib
/usr/local/lib
- App bundle's internal folders (if bundled)
macOS Tips:
- Set
DYLD_LIBRARY_PATH
before running:export DYLD_LIBRARY_PATH=/Users/me/mylibs ./myapp
- Or use:
OpenLibrary(0, "/Users/me/mylibs/libexample.dylib")
Summary Table
OS | Can Load From | Env Variable |
---|---|---|
Windows | CWD, EXE dir, System32, PATH | "%PATH%" |
Linux | CWD, "/usr/lib", custom paths | "LD_LIBRARY_PATH" |
macOS | CWD, "/usr/lib", app bundle paths | "DYLD_LIBRARY_PATH" |
Best Practice:
- Use full or relative paths in
OpenLibrary()
when possible. - Don’t assume the current directory is always searched (especially on macOS or newer Linux distros with stricter security settings).
- If you distribute your app with shared libs, place them in a known location relative to the executable and resolve paths at runtime.