簡體   English   中英

如何將C ++類與Java連接?

[英]How can I interface a C++ class to Java?

我目前正致力於通過JNI將C ++代碼與DLL依賴項集成到Java中。 我需要保留C ++的對象實例,以便通過Java進行后續調用。

任何人都可以幫助我理解如何將類實例傳遞給Java。 感謝這里的幫助。

#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <UIL.hpp>
#include <DeviceInfo.hpp>

typedef HINSTANCE LibraryHandle;
// pre-define UIL library entry points
typedef UIL* create_uil(const char*, bool, int, const char**);
typedef void delete_uil(UIL*);

const char* uilDriver;
bool uilAbsolute;
int uilParmCount;
static LibraryHandle uilHandle;

int _tmain(int argc, _TCHAR* argv[])
{
   uilHandle = LoadLibrary(TEXT("UIL.dll"));    
   if (uilHandle != NULL)
   {
      create_uil* createUIL = (create_uil*)GetProcAddress(uilHandle, "createUIL");
      uil = createUIL(uilDriver, uilAbsolute, uilParmCount, uilParms);  
      **//I need to return the instance UIL to JAVA**
   }
}

UIL.hpp

class UIL {
public:

  //! constructor for the UIL
    UIL(const char * driver_name, bool absolute, int parm_count, const char* parms[]);
  ~UIL();
  CPPEXTERN void infoString(char* str, int size);
  CPPEXTERN int deviceCount();
  CPPEXTERN int getDeviceKey(int index);
  int getCurrentDevice();
  CPPEXTERN int getCurrentDeviceIndex();
  int setDevice(int key);
  CPPEXTERN int setDeviceIndex(int index);
  CPPEXTERN int getDeviceInfo(DeviceInfo* di);
  CPPEXTERN int getAllDevices(DeviceInfo* di, int array_size);
  CPPEXTERN int send(unsigned char* buffer);
  CPPEXTERN int getNumWaiting(int &waiting);
  CPPEXTERN int receive();
  CPPEXTERN int lockDevice(int index, bool lock);
  CPPEXTERN bool isLocked(int index);
  CPPEXTERN int receiveInfo(int command_code, int argc, ...);
  CPPEXTERN int ioctl(int command_code, int argc, ...);
  CPPEXTERN int errInfo(int command_code, int argc, ...);
  int deviceListChangeCallback();
  CPPEXTERN void setLoggingLevel(int level);
  void getVersion(int& major, int& minor, int& revision);
  void getDriverVersion(int& major, int& minor, int& revision);
  const char* errStr(int err_code);
  UILAbstractDriver * getDriver() { return driver; }

private:
  UILAbstractDriver* driver;
  int last_key;
  int key_map[MAX_DEVICE_COUNT];
  int logging_level;
  char driver_name[81];
  void* io_argv[50];
  int device_index;
};

我找到了使用JNA的答案解決方案:

#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <UIL.hpp>
#include <DeviceInfo.hpp>

typedef HINSTANCE LibraryHandle;
// pre-define UIL library entry points
typedef UIL* create_uil(const char*, bool, int, const char**);
typedef void delete_uil(UIL*);

const char* uilDriver;
bool uilAbsolute;
int uilParmCount;
static LibraryHandle uilHandle;

extern "C" __declspec(dllexport) UIL* Initialize(int hba, int port)  
{
   uilHandle = LoadLibrary(TEXT("UIL.dll"));    
   if (uilHandle != NULL)
   {
      create_uil* createUIL = (create_uil*)GetProcAddress(uilHandle, "createUIL");
      uil = createUIL(uilDriver, uilAbsolute, uilParmCount, uilParms);  
      return uil;              }
}

JAVA

public interface UILInterfaceNative extends Library{
    public PointerByReference Initialize(int hba, int port);
    public int Scan(PointerByReference uil);
}

public class Main {

    /**
     * @param args the command line arguments
     */        
    public static void main(String[] args) {
        // TODO code application logic here
        UILInterfaceNative uil = (UILInterfaceNative)Native.loadLibrary("UILInterfaceNative", UILInterfaceNative.class);
        PointerByReference uilPointer = new PointerByReference();
        uilPointer = uil.Initialize(0, 2);
        int device = uil.Scan(uilPointer);
        System.out.println("Device found: " + device);
    }   
}

我建議您使用SWIG在jni中自動生成java本機方法和相應的方法,它可以節省您所需的時間,即定義一個包含指定頭文件中定義的方法的配置文件。 這是一個例子

jni_interface.i

%module MyNativeModule

%{
#include "native_header_file.h"
#include "native_header_file2.h"
%}

%include "arrays_java.i";
%include "enumtypeunsafe.swg"
%javaconst(1);

%pragma(java) jniclasscode=%{
    static {
        try {
            java.lang.System.loadLibrary("my-native-lib");
        } catch (UnsatisfiedLinkError e) {
            java.lang.System.err.println("my-native-lib native code library failed to load.\n" + e);
            java.lang.System.exit(1);
        }
        try {
            java.lang.System.loadLibrary("my-native-lib2");
        } catch (UnsatisfiedLinkError e) {
            java.lang.System.err.println("my-native-lib2 native code library failed to load.\n" + e);
            java.lang.System.exit(1);
        }
        try {
            java.lang.System.loadLibrary("my-native-lib3");
        } catch (UnsatisfiedLinkError e) {
            java.lang.System.err.println("my-native-lib3 native code library failed to load.\n" + e);
            java.lang.System.exit(1);
        }        
    }
%}

%include "native_header_file.h"
%include "native_header_file2.h" of a config file:

因此,基本上您可以指定包含要在Java中使用的方法的頭文件以及要加載的本機庫。

這是一個.bat,你可以在每次更改本機方法時自動運行swig並重新生成方法。

swig.bat

rd java\com\demo\my_project_name\my-native-core\headers /Q /S
md java\com\demo\my_project_name\my-native-core\headers
swig.exe -java -package com.demo.my_project_name.my-native-core.headers -includeall -verbose -outdir java\com\demo\my_project_name\my-native-core\headers -c++ -I\usr\local\include -I\System\Frameworks\JavaVM.frameworks\Headers -I.\jni -o jni\jiw.cpp jni_interface.i

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM