我有一些代码可以与使用C ++工作的Windows上的硬件设备进行通信。代码做了一些非常简单的事情来对设备上的按钮进行反应,并且我将它编译成带有观察者的dll,当按下按钮时调用该观察者。我现在需要将它与一个大型Java程序连接起来。
我打算使用JNA,但它只适用于C,我无法看到如何使用C中的Observer模式执行此操作。我已经研究过使用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方。
答案 0 :(得分:2)
听起来你正在寻找SWIG的directors feature。在最简单的形式中,您可以通过提供如下界面文件来使用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:
swig -Wall -java -c++ mymodule.i
这将生成三个Java类:MyModule
,MyModuleJNI
和Observer
。其中MyModule
将包含头文件中的所有自由函数,公开为static
成员函数,因为Java没有自由函数这样的东西。您可以放心地忽略MyModuleJNI
- 它是SWIG生成的用于将MyModule
连接到真正的C ++实现的粘合剂。您需要为MyModuleJNI
编译mymodule_wrap.cxx(因此MyModule
)才能正常工作,并在调用任何函数之前使用System.loadLibrary
加载DLL。
Observer
类直接对应mydll.h
中的Observer接口。您应该使用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特殊情况下的一些包装。