将DLL包装到Java中 [英] Wrap a DLL into Java

查看:84
本文介绍了将DLL包装到Java中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码可以和在C ++中运行的Windows上的硬件设备进行通讯.该代码可以对设备上的按钮按下作出反应,非常简单,我将其与一个观察器一起编译为dll,该观察器在按下按钮时被调用.我现在需要将此接口与一个大型Java程序进行接口.

I've got some code to talk to a hardware device on windows which is working in C++. The code does something pretty simple to react to a button push on the device and I have this compiled into a dll with an observer that is called when the button is pushed. I now need to interface this with a big Java program.

我打算使用JNA,但它只能与C一起使用,而我看不到如何使用C中的Observer模式来做到这一点.我已经研究过使用BridJ和SWIG(两者都适用于C ++ DLL)创建与已编译的dll(具有关联的头文件)的接口,但是BridJ创建了大量的文件(在JNAeratorStudio中),然后因错误而停止,并且我看不到如何在Windows上使用SWIG入门(我正在使用Visual Studio Express,而不是完整的Visual Studio.

I was intending to use JNA but it only works with C and I cannot see how to do this with an Observer pattern in C. I've looked into using BridJ and SWIG (both of which cliam to work on C++ DLLs) to create an interface to the compiled dll (with the associated header file) but BridJ creates huge amounts of files (in JNAeratorStudio) and then stops with an error and I cannot see how to get started on Windows with SWIG (I'm using Visual Studio Express rather than full Visual Studio).

没有人知道有关将C ++ DLL与Java程序集成的教程-SWIG看起来很有前途,但这些教程是沼泽的".

Does anyone know of a tutorial on integrating a C++ DLL with a Java Program - SWIG looks pretty promising but the tutorials are 'swampy'.

我已经将一些简单的C代码与下面的DLL进行了对话:

I've put some simple C code to talk to the DLL below:

#include <iostream>
#include <stdio.h>

#include "DeepFocusControlDll.h"

using namespace std;
using namespace DeepFocusControl;

class MyObserver : public DeepFocusControl::DeepFocusObserver{
    void Event(){
        printf("***Button Pushed***");
    }
};

int main()
{
    DeepFocusControl::AVA6Control* dfc = new DeepFocusControl::AVA6Control();
    MyObserver* observer = new MyObserver();
    dfc->AddObserver(observer);
    bool connected = dfc->IsConnected();
    printf("Connected %s\n", (connected)?"true":"false");
    bool connectresult = dfc->Connect();
    printf("Connecting %s\n", (connectresult)?"true":"false");
    connected = dfc->IsConnected();
    printf("Connected %s\n", (connected)?"true":"false");
    dfc->SetHardwareAppLaunch(false);
    char waitChar;
    cin >> waitChar;
    dfc->SetHardwareAppLaunch(true);
    dfc->RemoveObserver(observer);
    dfc->Disconnect();
    printf("Disconnected\n");
    cin >> waitChar;
}

如果有人知道使用观察者模式的更简单方法,我也可以很高兴地重新编码C端.

If anyone knows a simpler way to use an observer pattern on this I can happily recode the C side too.

推荐答案

听起来您正在寻找SWIG的导演功能.以最简单的形式,您可以通过提供如下接口文件来将Director与SWIG结合使用:

It sounds like you're looking for SWIG's directors feature. In its simplest form you can use directors with SWIG by giving an interface file like:

%module(directors=1) MyModule
%feature("director");         

%{
#include "mydll.h"
%}

%include "mydll.h"

给出头文件"mydll.h":

Given a header file "mydll.h":

class Observer {
public:
  virtual void frobination() = 0;
  virtual ~Observer() {}
};

inline void bar(Observer *o) {
  o->frobination();
}

然后您可以运行SWIG:

Then you can run SWIG:


swig -Wall -java -c++ mymodule.i

这将生成三个Java类:MyModuleMyModuleJNIObserver.其中的MyModule将包含您的头文件中的所有自由函数,并以static成员函数的形式公开,因为Java没有自由函数之类的东西.您可以放心地忽略MyModuleJNI-它是SWIG生成的用于将MyModule连接到实际C ++实现的粘合.您需要为MyModuleJNI(因此是MyModule)编译mymodule_wrap.cxx以使其正常工作,并使用System.loadLibrary加载DLL,然后再从它们中调用任何函数.

This will generate three Java classes: MyModule, MyModuleJNI and Observer. Of these MyModule will contain all the free functions from your header file, exposed as static member functions since Java has no such thing as free functions. You can safely ignore MyModuleJNI - it's glue generated by SWIG for connecting MyModule to the real C++ implementations. You'll need to compile mymodule_wrap.cxx for MyModuleJNI (and hence MyModule) to work correctly though and load the DLL using System.loadLibrary before you call any functions from them.

Observer类直接对应于mydll.h中的Observer接口.您应该使用Java派生它,并覆盖frobinate函数以为其提供自己的实现:

The Observer class directly corresponds to the Observer interface in mydll.h. You should derive from it in Java and override the frobinate function to give it your own implementation:

public class Test extends Observer {
  @Override
  public void frobination() {
    System.out.println("go go gadget frobinator");
  }

  public static void main(String[] argv) {
    System.loadLibrary("mymodule");
    Test t = new Test();
    MyModule.bar(t);    
  }
}

我可以编译并运行它来完成您希望的工作.

Which I can compile and run to do exactly what you'd hope.

如果需要,您可以通过添加以下内容来自动进行System.loadLibrary的呼叫:

If you want you can automate the call to System.loadLibrary by adding:

%pragma(java) jniclasscode=%{
  static {
    try {
        System.loadLibrary("mymodule");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. \n" + e);
      System.exit(1);
    }
  }
%}

到您的SWIG界面文件.

to your SWIG interface file.

如果真正的头文件是如此简单,那么获得相同结果也应该如此简单.如果更复杂,则可以指示SWIG以各种方式对某些特殊包装进行特殊处理.

If your real header file is that simple it should be that simple to get the same results too. If it's more complicated you can instruct SWIG to special case some of its wrapping in various ways.

这篇关于将DLL包装到Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆