java - 如何给jni dll函数名添加前缀

标签 java dll java-native-interface package default-package

我有一个 jni dll,它具有从 java 调用的函数。问题是这个dll包含默认包中的所有java类(在dll“Java_classname_methodname”中)。不可能获得这个 dll 的源代码,并且重写需要很长时间。所以我基本上需要从不同于默认包的 java 中调用这个 dll 中的函数。我已经连续几个小时尝试使用十六进制编辑器和几个工具来重命名 dll 中的函数来修改 dll 中的校验和和地址,但这对我来说太多了,因为我几乎没有这方面的经验。我非常喜欢这条路线,但我只是没有合适的工具或专业知识。所以我剩下的就是尝试在 java 中对包名称进行硬编码。我尝试使用 jna,如 this 中所述。堆栈溢出帖子执行以下操作:

Map options = new HashMap();

options.
    put(
        Library.OPTION_FUNCTION_MAPPER, 
        new StdCallFunctionMapper() {
            public String getFunctionName(NativeLibrary library, Method method) {
                method.setName(method.getName().replace("com.test.", "");
                return super.getFunctionName(library, method);
            }
        }
    );

Native.loadLibrary(..., ..., options);

但是Method中没有setName。理想情况下,我希望在没有任何额外库的情况下完成此任务,但我显然不反对使用像 jna 这样的东西。在有人问之前,是的,这是图书馆的使用许可证允许的。请不要告诉我这是不可能的,因为你知道这是可能的,只是很困难。无论采用哪种方式,我都愿意投入工作(修改 dll 或使用带有某些外部库的 java 代码)。顺便说一句,我最终还需要在 .so 和 .dylib 文件上完成此操作(不像 dll 那么重要)。感谢您抽出时间。

最佳答案

I have a JNI dll that has functions being called from java. The problem is that this DLL has all the java classes in the default package (in the dll "Java_classname_methodname").

因此具有 native 方法的相应 Java 类也不在包中。

It is impossible to get the source of this dll and it would take EXTREMELY long to rewrite. So I basically need to call the functions in this dll from java in a different package than default.

正确。

I've tried for hours on end to rename the functions in the dll with a hex editor and several tools to modify the checksum and addresses in the dll but it's just too much for me because I have almost no experience with this.

您也许可以以某种方式为函数名称添加别名,但自从我在该领域实践以来已经有大约 20 年了。

I would very much prefer this route, but I just don't have the proper tools or the know-how. So what I'm left with is trying to hardcode the package name in java.

没有。没有可硬编码的包名称。您剩下的就是尝试从包中的类调用没有包的类中的 native 方法,从 1.4 开始这是不可能的。

您需要做的是:

  1. 可以通过反射调用无包的 Java 原生方法。因此,您可以编写一个执行此操作的包装器类,该类位于您选择的包中,并且其余代码可以调用该包装器。

或者

  • 如下:

    • 使用适当的 native 方法在您选择的包中编写另一个 Java 类。
    • 从现有 DLL 创建导入库。
    • 编写另一个 DLL 并将其与此导入库链接。
    • 从 Java 代码中加载这个新的 DLL。
    • 让这个 DLL 使用 RegisterNatives初始化时的方法,以在新的 native 方法名称和签名下注册旧 DLL 中现有的 JNI 入口点。
    • 使用 javah 获取所需的 native 方法名称,并使用 javap 获取所需的 Java 签名。不要试图用手去猜测它们。
  • 不要问我这是如何映射到 .so 文件的。

    关于java - 如何给jni dll函数名添加前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38864363/

    相关文章:

    java - JNI : vcvars32. bat 给我 "Cannot open include file: ' stdio.h': No such file or directory"

    java - 通过 java URLConnection 登录 facebook

    java - 在java中构建应用程序主机(例如wordpress.com或google group)的可能解决方案是什么?

    c# - 没有将所有类编译成dll

    android - 不能在两个不同的类中使用外部 JNI 函数,不满足链接错误

    android - 使用 FFMPEG 和 JNI 压缩视频

    java - 可以使用 Retrofit 进行 SOAP web 服务调用吗?

    java - 如何在 tomcat 6 web.xml servlet-mapping servlet-pattern 中定义子路径

    c# - 在 Visual Studio 2015 中调试 native 应用程序加载的托管 DLL

    c# - 如何在 wpf/winforms 应用程序中将 DLL 与 .exe 组合(包含图片)