英文:
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)
如果我们在解决了pip
和cffi
依赖关系后使用命令python plugin.py
运行,您将在当前目录中获得my_plugin.c
和MyDllPlugin-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("""
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)
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("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);
}
}
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("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());
}
}
Output:
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>
Can anyone help to call Python DLL in Java using Java(JNA)?
专注分享java语言的经验与见解,让所有开发者获益!
评论