#1964 Mac OS issue when loading SDRPlay API native library from fully qualified path. (#1965)

Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
Denny Sheirer
2024-09-02 05:11:03 -04:00
committed by GitHub
parent d7fbbcefc5
commit 298d9d7016
5 changed files with 108 additions and 23 deletions

View File

@@ -42,6 +42,7 @@ As a final step, delete the original api version branches and rename each of the
Code Modifications: for each version, modify the sdrplay_api_h.java class to wrap the SYMBOL_LOOKUP variable using the
following changes, so that the code doesn't throw an error on systems that don't have the API installed:
//jextract auto-generated code modified to wrap with exception handler for systems that don't have the library
static SymbolLookup SYMBOL_LOOKUP;
static
@@ -54,10 +55,33 @@ following changes, so that the code doesn't throw an error on systems that don't
}
catch(Exception e)
{
SYMBOL_LOOKUP = null;
if(SDRPlayLibraryHelper.LOADED_FROM_PATH)
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(SDRPlayLibraryHelper.LIBRARY_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e2)
{
SYMBOL_LOOKUP = null;
}
}
else
{
SYMBOL_LOOKUP = null;
}
}
}
... and add null checking to the findOrThrow() method ...
if(SYMBOL_LOOKUP == null)
{
throw new UnsatisfiedLinkError("unresolved symbol:" + symbol);
}
IntelliJ setup
1. Run configuration
2. JVM Option: --enable-native-access=ALL-UNNAMED

View File

@@ -42,22 +42,22 @@ public class SDRPlayLibraryHelper
private static final String SDRPLAY_API_PATH_MAC_OS = "/usr/local/lib/libsdrplay_api.dylib";
private static final String SDRPLAY_API_PATH_MAC_OS_ALTERNATE = "/usr/local/lib/libsdrplay_api.so";
private static final String SDRPLAY_API_PATH_WINDOWS = System.getenv("ProgramFiles") +
"\\SDRplay\\API\\" + (System.getProperty("sun.arch.data.model").contentEquals("64") ? "x64" : "x86") +
"\\" + SDRPLAY_API_LIBRARY_NAME;
private static final String JAVA_LIBRARY_PATH_KEY = "java.library.path";
public static final boolean LOADED = load();
"\\SDRplay\\API\\x64\\" + SDRPLAY_API_LIBRARY_NAME;
/**
* Attempts to load the SDRPlay API library from the local system.
*
* @return true if library was loaded successfully.
*/
public static boolean load()
public static final boolean LOADED;
public static final boolean LOADED_FROM_PATH;
public static final Path LIBRARY_PATH = Path.of(getSDRplayLibraryPath());
static
{
boolean loaded = false;
boolean loadedFromPath = false;
try
{
System.loadLibrary(SDRPLAY_API_LIBRARY_NAME);
return true;
mLog.info("SDRPLay API library loaded by name [" + SDRPLAY_API_LIBRARY_NAME + "]");
loaded = true;
}
catch(Throwable t)
{
@@ -70,11 +70,13 @@ public class SDRPlayLibraryHelper
try
{
System.load(libraryPath);
return true;
mLog.info("SDRPLay API library loaded by path [" + libraryPath + "]");
loaded = true;
loadedFromPath = true;
}
catch(Throwable t2)
{
mLog.warn("Unable to load SDRPlay API native library: " + libraryPath);
mLog.info("SDRPlay API native library not found at " + libraryPath);
}
}
else
@@ -83,7 +85,8 @@ public class SDRPlayLibraryHelper
}
}
return false;
LOADED = loaded;
LOADED_FROM_PATH = loadedFromPath;
}
/**
@@ -115,9 +118,4 @@ public class SDRPlayLibraryHelper
mLog.error("Unrecognized operating system. Cannot identify sdrplay api library path");
return "";
}
public static void main(String[] args)
{
System.out.println("Loaded: " + SDRPlayLibraryHelper.LOADED);
}
}

View File

@@ -21,6 +21,7 @@
package io.github.dsheirer.source.tuner.sdrplay.api.v3_07;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayLibraryHelper;
import java.lang.foreign.AddressLayout;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
@@ -57,6 +58,10 @@ public class sdrplay_api_h {
}
static MemorySegment findOrThrow(String symbol) {
if(SYMBOL_LOOKUP == null)
{
throw new UnsatisfiedLinkError("unresolved symbol:" + symbol);
}
return SYMBOL_LOOKUP.find(symbol)
.orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol));
}
@@ -95,7 +100,23 @@ public class sdrplay_api_h {
}
catch(Exception e)
{
SYMBOL_LOOKUP = null;
if(SDRPlayLibraryHelper.LOADED_FROM_PATH)
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(SDRPlayLibraryHelper.LIBRARY_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e2)
{
SYMBOL_LOOKUP = null;
}
}
else
{
SYMBOL_LOOKUP = null;
}
}
}

View File

@@ -21,6 +21,7 @@
package io.github.dsheirer.source.tuner.sdrplay.api.v3_08;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayLibraryHelper;
import java.lang.foreign.AddressLayout;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
@@ -57,6 +58,10 @@ public class sdrplay_api_h {
}
static MemorySegment findOrThrow(String symbol) {
if(SYMBOL_LOOKUP == null)
{
throw new UnsatisfiedLinkError("unresolved symbol:" + symbol);
}
return SYMBOL_LOOKUP.find(symbol)
.orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol));
}
@@ -95,7 +100,23 @@ public class sdrplay_api_h {
}
catch(Exception e)
{
SYMBOL_LOOKUP = null;
if(SDRPlayLibraryHelper.LOADED_FROM_PATH)
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(SDRPlayLibraryHelper.LIBRARY_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e2)
{
SYMBOL_LOOKUP = null;
}
}
else
{
SYMBOL_LOOKUP = null;
}
}
}

View File

@@ -21,6 +21,7 @@
package io.github.dsheirer.source.tuner.sdrplay.api.v3_15;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayLibraryHelper;
import java.lang.foreign.AddressLayout;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
@@ -57,6 +58,10 @@ public class sdrplay_api_h {
}
static MemorySegment findOrThrow(String symbol) {
if(SYMBOL_LOOKUP == null)
{
throw new UnsatisfiedLinkError("unresolved symbol:" + symbol);
}
return SYMBOL_LOOKUP.find(symbol)
.orElseThrow(() -> new UnsatisfiedLinkError("unresolved symbol: " + symbol));
}
@@ -95,7 +100,23 @@ public class sdrplay_api_h {
}
catch(Exception e)
{
SYMBOL_LOOKUP = null;
if(SDRPlayLibraryHelper.LOADED_FROM_PATH)
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(SDRPlayLibraryHelper.LIBRARY_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e2)
{
SYMBOL_LOOKUP = null;
}
}
else
{
SYMBOL_LOOKUP = null;
}
}
}