java - 从 Java 调用 C++ 函数。映射 "const char*"

标签 java c++ java-native-interface native

我已经通过 stackoverflow 和互联网搜索了这个问题,但尚未找到答案。

我有一个指纹识别器的 SDK,但我没有源代码,这意味着我无法更改它。

它有一些我需要访问的方法,我将在下面列出哪些接口(interface)(来自 RS_API.h):

REALSCANSDK_API int __stdcall RS_InitSDK( const char* configFileName, int option, int* numOfDevice );
REALSCANSDK_API int __stdcall RS_InitDevice( int deviceIndex, int*deviceHandle );
REALSCANSDK_API int __stdcall RS_SetCaptureMode( int deviceHandle, int captureMode, int captureOption, bool withModeLED );
REALSCANSDK_API int __stdcall RS_SetViewWindow( int deviceHandle, HWND windowHandle, RECT drawRectangle, bool autoContrast );
REALSCANSDK_API int __stdcall RS_TakeImageDataEx( int deviceHandle, int timeout, int fingerIndex, bool withLED, unsigned char** imageData, int* imageWidth, int* imageHeight );

我设法将它们全部转换为 Delphi,但我还想从 java 应用程序访问它。

我的原型(prototype)是这样的:

public class Leitor {
    public native int  RS_InitSDK(String configFileName, int option, int numOfDevice );

    public static void main(String[] args) {
        Leitor leitor= new Leitor();
        leitor.RS_InitSDK(null, 0, 0);
    }
  static 
  {
    System.load("C:\\temp\\SDKSuprema\\SDK\\RS_SDK.dll");    
  }
}

加载位工作正常(我相信这意味着它可以找到dll文件),但是当它运行 native 方法时它会抛出异常:

线程“main”中出现异常 java.lang.UnsatisfiedLinkError: leitor.Leitor.RS_InitSDK(Ljava/lang/String;II)I 在 leitor.Leitor.RS_InitSK( native 方法) 在 leitor.Leitor.main(Leitor.java:14)

如果我重命名该 dll,它会将错误更改为“无法加载库”,因此我认为问题出在方法的映射上。

我也找不到如何映射要从 Java 调用的按引用传递参数。唯一的解决方案是更改 dll 以返回一个结构而不是单个结果,但这是不可能的,因为我无法更改代码。

第二个问题是将窗口句柄从 swt 发送到 JNI native 方法...

非常欢迎任何帮助!

最佳答案

您需要编写显式粘合代码,该代码接受参数作为 Java 对象并将它们转换为现有 C 入口点期望的表示形式。 JVM 本身不会为您执行此操作。

阅读JNI specification了解如何编写此粘合代码。

特别是,为了匹配您的 Java 声明,JNI 入口点必须命名为 package_name_here_Leitor_RS_1InitSDKpackage_name_here_Leitor_RS_1InitSDK__Ljava_lang_String_2II;请参阅规范第 2 章的“解析 native 方法名称”部分。该函数必须在 Java 可见参数前面接受一些额外的参数;请参阅规范中的“ native 方法参数”。

在该方法中,您将字符串作为 jstring 值传递,您必须使用 JVM 中的 GetStringUTFChars 辅助函数将其转换为 C 字符串。

对于按引用传递参数,您需要找到一种对调用 Java 代码有意义的模拟它们的方法,例如传递一个其字段由您的 JNI 代码分配的对象,或者(快速而肮脏地) )传递一个 int[],其第一个元素由您的 JNI 代码分配。

关于java - 从 Java 调用 C++ 函数。映射 "const char*",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13312734/

相关文章:

Java hashCode方法最大返回值

java - 过多的迭代使数据结构变得困惑

c++ - 短内联函数的 const 正确性是否重要?

c++ - 虚拟异常类导致动态链接器错误

c++ - 有类似 is_empty_but_has_virtual_functions 的东西吗?

java - 如何在 JNI 中处理 Java 10 的 -classpath 属性

java - android jni返回多个变量

java - 为什么在添加 SpinnerDateModel 时我的 JSpinner 会调整到比需要的更大?

java - 未能在java上制作我自己的绘图小部件

android - native 代码 - 如何以编程方式获取函数调用堆栈(回溯)