假设我加载了一个具有函数get_gg()的
本机库gg3
,并且想要加载另一个也具有get_gg()
函数的本机库gg4
- 我如何以“库感知”方式查找一个(例如,在某些情况下使用gg4
中的get_gg(),
否则使用gg3中的get_gg
)?
我尝试了CLinker.systemCLinker().lookup(),
但这似乎只是获取在加载的本机库中找到的第一个符号。
在内部类中搜索后,我发现SystemLookup.libLookup()
似乎很有希望但不公开,因此我实现了一个类似的方法来查找加载的本机库:
private static SymbolLookup libLookup(Function<NativeLibraries, NativeLibrary> loader) {
NativeLibrary lib = loader.apply(NativeLibraries.rawNativeLibraries(SystemLookup.class, false));
return name -> {
Objects.requireNonNull(name);
try {
long addr = lib.lookup(name);
return addr == 0 ?
Optional.empty() :
Optional.of(NativeSymbol.ofAddress(name, MemoryAddress.ofLong(addr), ResourceScope.globalScope()));
} catch (NoSuchMethodException e) {
return Optional.empty();
}
};
}
然而,这显然是被禁止的,因为我不能从另一个类装入器装入库(我不知道最初使用的是哪个类装入器):
java.lang.UnsatisfiedLinkError: Native Library already loaded in another classloader
所以我怎样才能找到
FWIW,完成这项工作所需的API在19年公开
在此之前,建议是通过绑定dlopen
、dlclo
和dlsym
(或Windows等价物)来手动实现它以加载库并查找符号。
e、 g.在我的Windows计算机上:
public class Main {
static final MethodHandle MH_LoadLibraryA;
static final MethodHandle MH_FreeLibrary;
static final MethodHandle MH_GetProcAddress;
static {
System.loadLibrary("Kernel32");
SymbolLookup lookup = SymbolLookup.loaderLookup();
CLinker linker = CLinker.systemCLinker();
MH_LoadLibraryA = linker.downcallHandle(
lookup.lookup("LoadLibraryA").orElseThrow(),
FunctionDescriptor.of(ADDRESS, ADDRESS));
MH_FreeLibrary = linker.downcallHandle(
lookup.lookup("FreeLibrary").orElseThrow(),
FunctionDescriptor.of(JAVA_INT, ADDRESS));
MH_GetProcAddress = linker.downcallHandle(
lookup.lookup("GetProcAddress").orElseThrow(),
FunctionDescriptor.of(ADDRESS, ADDRESS, ADDRESS));
}
static MemoryAddress LoadLibraryA(String name) {
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
return (MemoryAddress) MH_LoadLibraryA.invokeExact((Addressable) allocator.allocateUtf8String(name));
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
static boolean FreeLibrary(MemoryAddress handle) {
try {
return ((int) MH_FreeLibrary.invokeExact((Addressable) handle)) != 0;
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
static MemoryAddress GetProcAddress(MemoryAddress handle, String name) {
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
return (MemoryAddress) MH_GetProcAddress.invokeExact((Addressable) handle, (Addressable) allocator.allocateUtf8String(name));
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
static SymbolLookup libraryLookup(String libraryName, ResourceScope scope) {
MemoryAddress handle = LoadLibraryA(libraryName);
if (handle == MemoryAddress.NULL) {
throw new IllegalArgumentException("Cannot find library: " + libraryName);
}
scope.addCloseAction(() -> FreeLibrary(handle));
return name -> {
var addr = GetProcAddress(handle, name);
return addr == MemoryAddress.NULL ?
Optional.empty() : Optional.of(NativeSymbol.ofAddress(name, addr, scope));
};
}
public static void main(String[] args) throws Throwable {
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SymbolLookup lookup = libraryLookup("gg", scope);
MethodHandle handle = CLinker.systemCLinker().downcallHandle(
lookup.lookup("get_gg").orElseThrow(),
FunctionDescriptor.of(JAVA_INT));
int x = (int) handle.invoke();
System.out.println(x);
}
}
}
问题内容: 表1包含列:entry_id user_id …表2包含列:entry_id user_id … user_id条目并不总是相同的,因此我想将它们都提取出来,以便以后可以在脚本中对它们进行比较 我想提取t1.user_id和t2.user_id …问题是结果数组只有user_id 谢谢你 问题答案: 使用关键字:
问题内容: 我正在尝试获得类似这样的功能的参考: 我有以下错误: 如何获得具有指定参数的功能? 问题答案: 由于有两个名称相同但签名不同的方法,因此您必须指定所需的方法: 或者(如@Antonio正确指出的): 如果您需要将类的实例作为第一个参数的咖喱函数,则可以以相同的方式进行,只有签名不同(将@Antonios注释与您的问题进行比较):
问题内容: 我的问题是为什么我不能再次调用该函数?或者,如何做到这一点? 假设我有这个功能: 我称之为: 我得到4。 但是,假设我声明了一个与该函数同名的变量(错误): 现在,如果我尝试这样做: 要么: 我将收到此错误:“ TypeError:’int’对象不可调用” 无法将变量“ a”分配给函数? 问题答案: 完成此操作后: 不再是一个 函数 ,而只是一个 整数 (您已将其重新分配!)。因此,很
问题内容: 我在通过JPA使用sql本机查询选择某些数据时遇到了一些麻烦。那是因为我有3个名称相同的列“ descricao”。 当我通过 EntityManager 接口的 createNativeQuery 方法执行select操作时,找到的第一列值将覆盖其他值。 (例如,当我在一个对象数组中得到此结果时,给定记录的第一列描述的值为“ foo”,第二个“ bar”和第三个“ foobar”(因
问题内容: 我想解析一个json文件,但它经过这样的事情: 但是大约有三千个这样的对象。我一直在使用Gson解析我的json对象,但是我怎么解析这种文件呢?以及如何检索名称“ CDG”或“ ORY”? 问题答案: 您可以尝试如下操作: 使用gson,您可以按以下方式检索键名: 并使用java- json 可以执行以下操作: 从网址获取json:
问题内容: 我有一张供用户使用的表。但是,当用户对其个人资料进行任何更改时,我会将它们存储在临时表中,直到我批准它们为止。然后将数据复制到活动表中,并从临时表中删除。 我想要实现的是,在管理面板中或用户可以在提交前仔细检查的页面中查看数据时,我想编写一个查询,该查询将允许我从两个表中获取ID为ID的表中的数据两者都等于$ userid。然后,我想以表格形式显示它们,其中旧值显示在左列中,而新值显示