无法使用Python cffi从JNA调用在DLL中定义的函数。

huangapple 未分类评论67阅读模式
英文:

Not able to call functions defined in DLL using python cffi from JNA

问题

以下是翻译好的内容:

我已经使用cffi从Python文件plugin.py创建了一个DLL(代码如下所示)。我尝试使用JNA从Java中调用do_stuff()函数,但是我遇到了诸如“调用函数my_plugin.do_stuff(),但初始化代码失败。返回0。”的错误。它没有调用DLL中存在的Python函数。

我已经尝试使用JNA调用现有的Windows内核库Kernel32.dll,并且那是有效的,所以我不确定Windows DLL和我创建的DLL之间有什么区别。

代码:plugin.py

import cffi
ffibuilder = cffi.FFI()
ffibuilder.embedding_api("""
    int do_stuff(int, int);
""")
ffibuilder.set_source("my_plugin", "")
ffibuilder.embedding_init_code("""
    from my_plugin import ffi

    @ffi.def_extern()
    def do_stuff(x, y):
        print("adding %d and %d" % (x, y))
        return x + y
""")
ffibuilder.compile(target="MyDllPlugin-1.5.*", verbose=True)

如果我们在解决了pipcffi依赖关系后使用命令python plugin.py运行,您将在当前目录中获得my_plugin.cMyDllPlugin-1.5.dll文件。

调用MyDllPlugin-1.5.dll的Java代码

public class PythonToJavaDll {
    public interface NativeInterface extends Library {
        int do_stuff(int x, int y);
    }
    public static void main(String[] args) {
        System.out.println("Native Library started");
        NativeInterface nativeExample = (NativeInterface)Native.loadLibrary("MyDllPlugin-1.5", NativeInterface.class);
        int value = nativeExample.do_stuff(3,4);
        System.out.println("String value:" + value);
    }
}

输出:

Native Library started
function my_plugin.do_stuff() called, but initialization code failed.
Returning 0.
String value:0

然而,当我运行现有的C:/windows/System32/kernel32.dll文件时,我可以调用DLL的方法。

public class BeepExample {
    public interface Kernel32 extends Library {
        // FREQUENCY is expressed in hertz and ranges from 37 to 32767
        // DURATION is expressed in milliseconds
        public boolean Beep(int FREQUENCY, int DURATION);
        public void Sleep(int DURATION);
    }
    public static void main(String[] args) {
        System.out.println("Native Library started");
        Kernel32 lib = Native.loadLibrary("kernel32", Kernel32.class);
        System.out.println("Native Lib:" + lib);
        lib.Beep(698, 500);
        System.out.println("Sleep Started:" + new Date());
        lib.Sleep(500);
        System.out.println("Sleep End:" + new Date());
    }
}

输出:

Native Library started
Native Lib:Proxy interface to Native Library <kernel32.dll@140715486085120>
Sleep Started:Fri Aug 14 21:16:48 IST 2020
Sleep End:Fri Aug 14 21:16:48 IST 2020
Native Lib:Proxy interface to Native Library <kernel32.dll@140715486085120>

有谁能帮助解决使用Java(JNA)从Java中调用Python DLL的问题吗?

英文:

I have created a DLL from python file plugin.py (code is shown below) using cffi. I tried to call the do_stuff() function from Java using JNA, however I am getting errors like "function my_plugin.do_stuff() called, but initialization code failed. Returning 0." It is not calling the python function which is present in dll.

I have tried to call windows existing Kernel32.dll using JNA and that's working, so I am not sure what is the difference between the windows dll and my created DLL.

Code: plugin.py

import cffi
ffibuilder = cffi.FFI()
ffibuilder.embedding_api(&quot;&quot;&quot;
    int do_stuff(int, int);
&quot;&quot;&quot;)
ffibuilder.set_source(&quot;my_plugin&quot;, &quot;&quot;)
ffibuilder.embedding_init_code(&quot;&quot;&quot;
    from my_plugin import ffi

    @ffi.def_extern()
    def do_stuff(x, y):
        print(&quot;adding %d and %d&quot; % (x, y))
        return x + y
&quot;&quot;&quot;)
ffibuilder.compile(target=&quot;MyDllPlugin-1.5.*&quot;, verbose=True)

If we run with command python plugin.py after resolving pip and cffi dependency you will get my_plugin.c and MyDllPlugin-1.5.dll files in current directory.

Java code to call MyDllPlugin-1.5.dll

public class PythonToJavaDll {
	public interface NativeInterface extends Library {
	    int do_stuff(int x, int y);
    }
	public static void main(String[] args) {
	    System.out.println(&quot;Native Library started&quot;);
	    NativeInterface nativeExample = (NativeInterface)Native.loadLibrary(&quot;MyDllPlugin-1.5&quot;,NativeInterface.class);
	    int value = nativeExample.do_stuff(3,4);
	    System.out.println(&quot;String value:&quot;+value);
    }
}

output:

Native Library started
function my_plugin.do_stuff() called, but initialization code failed.  
Returning 0.
String value:0

However when I run existing C:/windows/System32/kernel32.dll file then I am able to call methods of DLL.

public class BeepExampl {
    public interface Kernel32 extends Library {
	    // FREQUENCY is expressed in hertz and ranges from 37 to 32767
    	// DURATION is expressed in milliseconds
	    public boolean Beep(int FREQUENCY, int DURATION);
	    public void Sleep(int DURATION);
	}
    public static void main(String[] args) {
	    System.out.println(&quot;Native Library started&quot;);
	    Kernel32 lib = Native.loadLibrary(&quot;kernel32&quot;, Kernel32.class);
	    System.out.println(&quot;Native Lib:&quot; + lib);
	    lib.Beep(698, 500);
	    System.out.println(&quot;Sleep Started:&quot; + new Date());
	    lib.Sleep(500);
	    System.out.println(&quot;Sleep End:&quot; + new Date());
	}
}

Output:

Native Library started
Native Lib:Proxy interface to Native Library &lt;kernel32.dll@140715486085120&gt;
Sleep Started:Fri Aug 14 21:16:48 IST 2020
Sleep End:Fri Aug 14 21:16:48 IST 2020
Native Lib:Proxy interface to Native Library &lt;kernel32.dll@140715486085120&gt;

Can anyone help to call Python DLL in Java using Java(JNA)?

huangapple
  • 本文由 发表于 2020年8月14日 23:57:15
  • 转载请务必保留本文链接:https://java.coder-hub.com/63416180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定