我正在尝试开发一个cdll的jna Package 器。
我没有访问dll代码的权限。我用depends.exe检查了dll,发现c方法周围没有装饰程序。看来 extern "C"
在我检索到的c++.h文件中也设置了。
但我有以下错误:
线程“main”java.lang.UnsatifiedLinkError中出现异常:查找函数“compute”时出错:找不到指定的过程。
在com.sun.jna.function。java:252)在com.sun.jna.nativelibrary.getfunction(nativelibrary。java:600)在com.sun.jna.nativelibrary.getfunction(nativelibrary。java:576)在com.sun.jna.nativelibrary.getfunction(nativelibrary。java:562)在com.sun.jna.library$handler.invoke(library。java:243)在com.sun.proxy.$proxy0.compute(未知源)上com.jna.main(jna。java:171)
查看我的cpp.h文件:
# ifdef __cplusplus
extern "C" {
# endif
typedef struct s_mine
{
e_color color; //e_color is enum type made of int values
his data;
int str;
unsigned int wild;
unsigned int hello;
float rice;
} mine;
typedef struct s_his
{
unsigned char * data;
unsigned int size;
} his;
// compute function which raised the exception
int compute(const his* const input, void**outputPointer);
// treat function raised also the same exception
int treat(const mine* inputParameter, mine* outputParameter);
# ifdef __cplusplus
}
# endif
请参见下面我的jna Package :
public interface MyInterface extends Library {
@FieldOrder({"data", "size"})
public static class his extends Structure {
public static class ByReference extends his implements Structure.ByReference {}
public static class ByValue extends rt_buffer implements Structure.ByValue {}
public Pointer data;
public int size;
}
@FieldOrder({"color","data","str","wild","hello","rice"})
public class mine extends Structure {
public static class ByReference extends mine implements Structure.ByReference {}
public int color;
public his data;
public int str;
public int wild;
public int hello;
public float rice;
}
public int compute(his input, Pointer[] outputPointer);
public int treat(mine inputParameter, mine outputParameter);
}
因此在我的测试课上我设置:
// COMPUTE
MyInterface.his.ByReference input_ref = new MyInterface.his.ByReference();
ByteBuffer init_buffer;
// init_buffer is initialized with some not null values
Pointer init_p = Native.getDirectBufferPointer(init_buffer);
input_ref.data = init_p;
input_ref.size = init_buffer.capacity();
Pointer[] outputPointer = null;
int resultCompute = compute(input_ref, outputPointer);
// TREAT
MyInterface.mine.ByReference inputParameter_ref = new MyInterface.mine.ByReference();
MyInterface.his.ByValue buffer = new MyInterface.his.ByValue();
// initialize buffer with an input buffer value different from null value
// Set other fields of inputParameter_ref with none null values
inputParameter_ref.data = buffer;
MyInterface.mine.ByReference outputParameter_ref = null;
int resultTreat = treat(inputParameter_ref, outputParameter_ref);
因此,我觉得引发的异常不是来自我的实现,而是来自dll。但是我没有任何线索来解释为什么我在我的帖子开始的时候这么说。
除了decorator和extern声明问题,还有其他原因吗?
如何使用depends.exe检查dll是否设置了extern声明?
@谢谢你的回复,但是:
consthisconstinput表示input是常量his结构上的常量指针。这意味着指针是readonlyvalue上的readonly参数。
我将outputpointer设置为数组,因为我不确定如何使用它。实际上,我需要它作为另一个方法的输入参数。对于c++来说,我有一些类似于:
int compute(const his const input, void**outputPointer); //**outputPointer is an output of compute method int manage(void * inputPointer); // As *outputPointer becomes an input of manage method
因此,我的jna Package 里有:
public int compute(his input, Pointer[] outputPointer); public int manage(Pointer inputPointer);
在我的测试课上,我有: Pointer[] outputPointer = null;
int resultCompute = compute(input_ref, outputPointer); int manage(outputPointer[0]);
无论如何,我也试着用你的建议如下:这样我在我的jna Package 里:
public int compute(his input, PointerByReference outputPointer); public int manage(Pointer inputPointer);
在我的测试课上,我有: PointerByReference outputPointer = null;
int resultCompute = myInterface.compute(input_ref, outputPointer); int myInterface.manage(outputPointer.getValue());
但我还是有同样的问题。不管在cdll中定义了什么方法,我都有相同的引发异常。我真的觉得这个问题不是来自我的jna实现。同样重要的细节是,在我的测试类中,我执行dll的上载:
Map options = new HashMap(); options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper() {
public String getFunctionName(NativeLibrary library, Method method) { System.out.println("method names = "+method.getName());
return super.getFunctionName(library, method); }
}); MyInterface myInterface = (MyInterface) Native.load("dllName",MyInterface.class,options);
上面的sysout显示被调用的当前方法的名称,即 method names = compute
显示。在调试代码时,我注意到他们的方法名有问题。但是,由于sysout显示了我在jna Package 器中声明的方法的名称,因此没有任何帮助。我刚刚用一个伪方法执行了一个快速测试,这个伪方法没有在cdll中定义,我有一个相同的错误:找不到过程。因此,我真的认为有一个问题,与该动态链接库,但我不知道如何找到它。。。
1条答案
按热度按时间mwyxok5s1#
最后,我不得不在java测试主类中添加一个调用 Package 器的行来解决我的问题:system.setproperty(“jna.library.path”,“c:\mywrapper\src\main\resources”);其中c:\mywrapper\src\main\resources是存储我的dll文件的文件夹。
但它并没有解释为什么我不需要为存储在同一文件夹中的其他dll设置这一行,因为我在我的环境变量中也声明了jna.library.path。