笔者使用以下版本(不同版本的openDDS对应ACE+TAO版本不同)
openDDS:3.14
ACE+TAO:6.5.12
perl:5.32.0.1-64bit
Visual Studio:Community 2019
jdk:jdk-8u111-windows-x64
建议把Perl、ACE+TAO+CIAO、OpenDDS都装在同一文件夹下(最好不要有中文路径),如下图
openDDS
下载地址:https://opendds.org/downloads.html
官方文档:http://download.objectcomputing.com/OpenDDS/OpenDDS-latest.pdf
注:选择对应的版本下载
zip
包或者tar
包即可
ACE+TAO
下载地址:最新版本:https://download.dre.vanderbilt.edu/;
选择其他版本:https://download.dre.vanderbilt.edu/previous_versions/
perl
下载地址:最新版本:https://strawberryperl.com/
选择其他版本:https://strawberryperl.com/releases.html
下载后点击安装,无脑安装即可
Visual Studio
下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
我这里选择[Community]
版本的下载,你也可以通过其他渠道下载.
注:下载的过程中要勾选以下几个地方,其他步骤无脑下一步即可(我也不知道不勾选会不会有问题,反正我是选上了)
把弹出窗口右边的滚动条下拉一下,下面还有需要注意的选项:
网盘打包下载地址:
链接:https://pan.baidu.com/s/1wNq96hw_kQ8G8cXHbCC2iw
提取码:6k8p
(1)ACE_ROOT, 值为解压路径:E:\Software\Work\OpenDDS\ACE_wrappers
(2)TAO_ROOT, 值为解压路径:E:\Software\Work\OpenDDS\ACE_wrappers\TAO
(3)DDS_ROOT, 值为解压路径:E:\Software\Work\OpenDDS\OpenDDS
在 Path 后添加%ACE_ROOT%\lib
、%ACE_ROOT%\bin
、%DDS_ROOT%\lib
和%DDS_ROOT%\bin
注意:这里添加Path路径时,按照下图分开写。尽量不要图省事把几个路径写在一起,因为我当初这样写编译一致出现问题!!!
在E:\Software\Work\OpenDDS\ACE_wrappers\ace 下新建一个空的配置文件 config.h
文件内容为:
#include "ace/config-win32.h"
至此:环境搭建完毕!!!
注:最好按照以下顺序进行编译
步骤1:使用VS2019打开文件ACE_vs2019.sln
步骤2:选择项目—重定目标解决方案,等待执行完毕即可
步骤3:(两种方式任选其一,推荐第二种方式)需要花费半个小时左右,不必理会,等待即可
方式一:
1、为了兼容后期使用Java,这里选择64位,因为我开始选择32位的,到后面就报错了。
2、生成—生成解决方案,等待执行完毕即可
3、执行成功的效果
方式二: 使用命令编译
步骤一: 打开命令行界面
步骤二: 打开命令行界面cd到要编译的文件目录下,使用如下命令进行编译:(同样这里也选择了64位编译)
msbuild ACE_vs2019.sln /p:Configuration=Debug;Platform=x64 /m:2
步骤同上:只需要更换目录和名称即可,这里编译过程时间可能会比上面的长一些,耐心等待即可
步骤一: 打开VS,使用命令行工具,cd到以下目录
步骤二: 执行命令
# 开启Java支持(前提是本机已经配置好Java环境)
.\configure --java
步骤三:检查opendds根目录中是否生成了DDS_no_tests.sln文件和setenv.cmd文件
步骤四:选择生成的DDS_no_tests.sln,右键使用VS打开,选择debug(64位)依次执行:重定目标解决方案—>生成解决方案
等待编译成功即可
至此:准备工作已经完毕!!!
OpenDDS安装好之后,下一步就是利用OpenDDS来开发通信项目了。不过在项目中应用OpenDDS之前,先消化一下OpenDDS安装包中自带的示例项目messenger,通过阅读messenger的源代码来熟悉一下OpenDDS提供的用来开发Java项目的类。
在开始看OpenDDS的示例项目之前,需要安装好OpenDDS,并且在编译OpenDDS的时候要开启Java支持,这是前提条件。
第一步,在IDEA创建空的maven项目ddstest,用这个项目来看OpenDDS自带的messenger项目的示例代码。因为Idea无法直接打开messenger项目,所以才要创建一个ddstest新项目,把messenger的源码拷贝到ddstest中去边运行边看。
第二步,ddstest项目中引入4个必要的jar包。具体方法:File - Project Structure -Libraries - 点击"+"号 - Java ,然后定位到 %DDS_ROOT%\lib,选中3个jar包:i2jrt.jar、OpenDDS_DCPS.jar、tao_java.jar,定位到%DDS_ROOT%\java\tests\messenger下\messenger_idl下,选中messenger_idl_test.jar。
这样以来项目建好了,所需要的的4个jar包也都加入到项目的libraries中了。详情见下图:
然后去%DDS_ROOT%\java\tests\messenger下,将publisher和subscriber两个目录下的TestPublisher、TestSubscriber、DataReaderListenerImpl三个java文件复制到ddstest项目的src目录下。
1)首先配置虚拟机选项:
Run菜单 - Edit Configurations,在 vm options 一栏填写:
-ea -Dopendds.native.debug=true -Djava.library.path=E:\dds\OpenDDS-3.13/java/tests/messenger/messenger_idl;E:\OpenDDS-3.13\lib
请按照自己的实际情况修改路径。由于已经配置了jar包,所以不需要再写-cp选项。
-Djava.library.path是用来配置JNI库路径,不写的话会提示找不到dll
去除 -Xcheck:jni 是为了屏蔽掉过多的JNI Warning
2)然后配置主程序参数:
在同一个窗口的 Program arguments一栏填写:
-DCPSBit 0 -DCPSConfigFile E:\dds\OpenDDS-3.13/java/tests/messenger/tcp.ini
同样按照自己的实际情况修改路径。这一行如果写在vm options中,就会提示”ERROR: Domain Participant Factory not found“,因为参数传递给了虚拟机而不是程序,导致无法创建DomainParticipantFactory
3)运行实例
按照以上配置,分别配置TestPublisher的run configuration和TestSubscriber的run configuration,配置两个,因为运行的时候,它们两个会同时运行,各自使用自己的run configuration。
单独启动一个Visual Studio开发人员命令行,在其中运行:
%DDS_ROOT%/bin/DCPSInfoRepo -o repo.ior
或者进入指定目录,运行:DCPSInfoRepo -o repo.ior
接着修改tcp.ini,将common块DCPSInfoRepo项的值修改成repo.ior所在位置,不要去掉"file://"前缀
例如:DCPSInfoRepo=file://D:\Soft\OpenDDS\dds\OpenDDS\java\tests\messenger\userMessenger\repo.ior
然后按照先subscriber,后publisher的顺序启动程序即可。
4)上传jar
包,为了方便后期项目的使用,我们可以使用maven命令将使用到的jar包上传到自己的maven仓库中:
mvn install:install-file -Dfile=D:/Soft/OpenDDS/dds/OpenDDS/lib/tao_java.jar -DgroupId=com.dds -DartifactId=tao_java.jar -Dversion=1.0.1 -Dpackaging=jar
// 格式说明
<path-to-file>: 要安装的JAR的本地路径 ./libs/json-simple-1.1.1.jar
<group-id>:要安装的JAR的Group Id
<artifact-id>: 要安装的JAR的 Artificial Id
<version>: JAR 版本
<packaging>: 打包类型,例如JAR
在以下目录下新建文件夹:userManager
以及文件UserManager.idl
,可以将示例1目录中的Messenger.idl
复制过来,然后修改内容,其他文件都是在接下来的步骤中生成的。
UserManager.idl
的文件内容为:
module UserManager {
#pragma DCPS_DATA_TYPE "UserManager::User"
#pragma DCPS_DATA_KEY "UserManager::User id"
@topic
struct User {
long id;
string name;
boolean sexual;
long age;
double height;
};
};
在以上目录中,使用cmd打开窗口,执行以下命令:
generate_export_file.pl UserManager > UserManager_Export.h
执行命令之后会在该目录下生成UserManager_Export.h
文件
在相同目录下新建文件UserManager.mpc
,可以把%OPENDDS_HOME%\java\tests\messenger\messenger_idl目录下的messenger_idl_test.mpc拷出来改一下:
UserManager.mpc
的文件内容为:
project: dcps_test_java {
idlflags += -Wb,stub_export_include=UserManager_Export.h \
-Wb,stub_export_macro=UserManager_Export
dcps_ts_flags+= -Wb,export_macro=UserManager_Export
idl2jniflags += -Wb,stub_export_include=UserManager_Export.h \
-Wb,stub_export_macro=UserManager_Export
dynamicflags += USERMANAGER_BUILD_DLL
specific {
jarname = UserManager
}
// Older versions of Visual Studio will create the intermediate directories
// in all-lowercase, so we have to create them first to get the correct case.
specific(vc71, vc8) {
prebuild += <%mkdir%> UserManager 2<%gt%> <%nul%> <%or%> <%cat%> <%nul%> <%gt%> <%nul%>
prebuild += <%mkdir%> classes<%slash%>UserManager 2<%gt%> <%nul%> <%or%> <%cat%> <%nul%> <%gt%> <%nul%>
}
TypeSupport_Files {
UserManager.idl
}
verbatim(gnuace, bottom, 1) {
idl_stubs: _UserTypeSupportTAOPeer.java
}
}
在上面目录中,使用cmd打开窗口,执行以下命令:(vs2019要换成自己对应的版本)
mwc.pl -type vs2019 -features java=1
执行命令之后在该目录下会生成一些文件.
使用VS打开生成的文件userManager.sln
,选择debug(64位),**依次执行:**重定目标解决方案—>生成解决方案;
此时,按照我们刚刚编写的mpc文件,就可以得到UserManager.jar
和 UserManagerd.dll
(因为是Debug模式下生成,如果是Release模式则不会有d),剩下的文件都可以删除了。
在编译过程中如果提示缺少 jni_md.h
文件,该文件位于 %JAVA_HOME%\include\win32 目录下,复制到 %OPENDDS_HOME%\java\idl2jni\runtime 目录下即可。
或者: 按照以下方法
我们打开之前创建的ddstest项目稍作修改。
首先是移除对messenger_idl_test.jar的依赖,并添加UserManager.jar。此时三个java文件肯定都会报错标红,把这些地方都改掉就好。
对TestPublisher进行修改:
第1处:
MessageTypeSupportImpl servant = new MessageTypeSupportImpl();
-> 修改为:
UserTypeSupportImpl servant=new UserTypeSupportImpl();
第2处:
MessageDataWriter mdw = MessageDataWriterHelper.narrow(dw);
Message msg = new Message();
msg.subject_id = 99;
int handle = mdw.register_instance(msg);
msg.from = "OpenDDS-Java";
msg.subject = "Review";
msg.text = "Worst. Movie. Ever.";
msg.count = 0;
int ret = RETCODE_TIMEOUT.value;
for (; msg.count < N_MSGS; ++msg.count) {
while ((ret = mdw.write(msg, handle)) == RETCODE_TIMEOUT.value) {
}
if (ret != RETCODE_OK.value) {
System.err.println("ERROR " + msg.count +
" write() returned " + ret);
}
try {
Thread.sleep(100);
} catch(InterruptedException ie) {
}
}
-> 修改为:
UserDataWriter writer=UserDataWriterHelper.narrow(dw);
User user=new User();
int handle=writer.register_instance(user);
user.name="zhangsan";
user.age=20;
user.sexual=true;
user.height=1.75;
user.id=1;
writer.write(user,handle);
对TestSubscriber进行修改:
MessageTypeSupportImpl servant = new MessageTypeSupportImpl();
-> 修改为:
UserTypeSupportImpl servant=new UserTypeSupportImpl();
对DataReaderListenerImpl进行修改:
先把Message全替换成User
if (mh.value.count < 0 || mh.value.count >= counts.size()) {
invalid_count = true;
}
else {
if (counts.get(mh.value.count) == false){
counts.set(mh.value.count, true);
}
else {
prefix = "ERROR: Repeat ";
}
}
System.out.println(prefix + "Messenger.User: subject = " + mh.value.subject);
System.out.println(" subject_id = "
+ mh.value.subject_id);
System.out.println(" from = " + mh.value.from);
System.out.println(" count = " + mh.value.count);
System.out.println(" text = " + mh.value.text);
System.out.println("SampleInfo.sample_rank = "
+ sih.value.sample_rank);
-> 修改为:
System.out.println("User "+mh.value.id+":{name:"+mh.value.name+",age:"+mh.value.age+",sexual:"+(mh.value.sexual?"male":"female")+",height:"+mh.value.height+"}");
然后把VM option中的 -Djava.library.path 修改为: -Djava.library.path=
;E:\dds\OpenDDS-3.13\lib
因为-DCPSConfigFile选项没改,所以还是在messenger示例目录下运行DCPSInfoRepo,分别运行TestPublisher和TestSubscriber后,在订阅者一端打印了如下消息,说明替换成功:
不同的版本对应的执行命令和方法可能略有不同,安装过程中也可能会有各种奇怪的错误,祝君好运!!!
参考教程:
https://blog.csdn.net/zhangzl4321/article/details/126351779
https://blog.csdn.net/zhangzl4321/article/details/126351804
https://blog.csdn.net/u010670411/article/details/86552739
https://blog.csdn.net/qq740874037/article/details/123804033
https://blog.csdn.net/qq740874037/article/details/125964357