0

我有一些代码可以与 Windows 上使用 C++ 工作的硬件设备通信。代码做了一些非常简单的事情来对设备上的按钮做出反应,我将它编译成一个带有观察者的 dll,当按钮被按下时调用该观察者。我现在需要将它与一个大型 Java 程序连接起来。

我打算使用 JNA,但它只适用于 C,我看不到如何使用 C 中的观察者模式来做到这一点。我研究过使用 BridJ 和 SWIG(这两个 cliam 都可以在 C++ DLL 上工作)来创建一个与已编译 dll 的接口(带有关联的头文件),但 BridJ 创建了大量文件(在 JNAeratorStudio 中),然后因错误而停止,我看不到如何使用 SWIG 在 Windows 上开始(我使用的是 Visual Studio Express 而不是比完整的 Visual Studio)。

有谁知道有关将 C++ DLL 与 Java 程序集成的教程 - SWIG 看起来很有希望,但这些教程是“沼泽”。

我放了一些简单的 C 代码来与下面的 DLL 对话:

#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 端。

4

1 回答 1

2

听起来您正在寻找 SWIG 的导演功能。在最简单的形式中,您可以通过提供如下接口文件来使用带有 SWIG 的导向器:

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

%{
#include "mydll.h"
%}

%include "mydll.h"

给定一个头文件“mydll.h”:

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

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

然后你可以运行 SWIG:

痛饮 -Wall -java -c++ mymodule.i

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

该类Observer直接对应 中的 Observer 接口mydll.h。您应该在 Java 中从它派生并覆盖该frobinate函数以提供您自己的实现:

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);    
  }
}

我可以编译并运行它来完全按照您的希望进行。

如果你愿意,你可以System.loadLibrary通过添加来自动调用:

%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 接口文件。

如果您真正的头文件如此简单,那么获得相同结果也应该如此简单。如果它更复杂,您可以指示 SWIG 以各种方式对其进行特殊处理。

于 2012-06-22T15:11:01.440 回答