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

Calling a C++ function from Java. Mapping "const char*"

本文关键字:const char 映射 Java 调用 C++ 函数      更新时间:2023-10-16

我已经通过stackoverflow和Internet搜索了这一点,但尚未找到答案。

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

它有一些我需要访问的方法,我将在下面列出哪个接口(来自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应用程序访问。

我的原型就是这样:

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文件),但是当它运行本机方法时,它会引发异常:

线程中的异常" main" java.lang.unsatisfiedlinkerror:leitor.ritor.rs_initsdk(ljava/lang/lang/string; ii)i 在leitor.leitor.rs_initsk(本机方法) 在leitor.leitor.main(leitor.java:14)

如果我重命名dll,则将错误更改为"无法加载库",所以我认为问题是方法的映射。

我也找不到从Java调用参考参数来映射通行证。唯一的解决方案是将DLL更改以返回结构而不是单个结果,但这是不可能的,因为我无法更改代码。

第二个问题是将窗口句柄从SWT发送到JNI本机方法...

非常欢迎任何帮助!

您需要编写以Java对象接受参数的明确胶代码,并将其转换为现有C入口点预期的表示。JVM本身不会为您做到这一点。

阅读JNI规范以学习如何编写此胶代码。

特别是,要匹配您的Java声明,必须将JNI入口点命名为package_name_here_Leitor_RS_1InitSDKpackage_name_here_Leitor_RS_1InitSDK__Ljava_lang_String_2II;请参阅规范第2章的"解决本地方法名称" 部分。此功能必须在Java可见的方面进行一些额外的论点。参见规格中的"本机方法参数"

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

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

您需要创建C/C 胶代码来实现Java方法,使用类调用Javah将创建一个标题,以声明本机标记为本机的Java方法。

如果您不想编写C/C ,则可以使用JNA将JAVA代码映射到现有的C方法和结构。