编译

官网链接 http://qpid.apache.org/components/messaging-api/index.html
源码包  qpid-cpp-1.36.0.tar.gz
生成解决方案工具 CMake


 1)浏览编译文档
    INSTALL-WINDOWS.txt文档描述了Windows编译Qpid的操作步骤以及注意事项,当前采用的是Microsoft Visual Studio 2015(VC14)编译Qpid,文档指定的编译器是Microsoft Visual Studio 2012(VC11)

2)编译依赖库
Qpid源码编译依赖库:
 * boost      <http://www.boost.org>                    (1.58)
 * CMake      <http://www.cmake.org>                    (3.2)
 * python     <http://www.python.org>                   (2.7.10)
 * ruby       <http://www.ruby-lang.org>                (2.2.2)
当前使用的是boost_1_59_0版本,CMake3.10.0rc1版本

如下库是可选的,所以没有安装
 * swig       <http://www.swig.org>                     (2.0.10)
 * perl       <http://www.perl.HELPME>                  (1.2.3)
 * nunit      <http://www.nunit.HELPME>                 (2.5.8)
 * doxygen

3) 默认选择生成的编译错误
选择创建BUILD_BINDING_DOTNET,出现如下的生成错误
Could NOT find SWIG (missing: SWIG_EXECUTABLE SWIG_DIR)
Building Dotnet bindings
CMake Error at bindings/qpid/dotnet/CMakeLists.txt:197 (message):
  No DOTNET binding support available for Visual Studio 14 2015
由于没有安装SWIG软件库,导致VS2015缺乏DOTNET binding套件,因此需要在CMake的配置选项中剔除BUILD_BINDING_DOTNET

选择创建BUILD_AMQP,出现如下的生成错误
CMake Error at src/amqp.cmake:47 (message):
  Qpid proton not found, required for amqp 1.0 support
Call Stack (most recent call first):
  src/CMakeLists.txt:591 (include)
由于没有安装Qpid proton,因此需要在CMake的配置选项中剔除BUILD_AMQP

CMake Deprecation Warning at CMakeLists.txt:138 (cmake_policy):
  The OLD behavior for policy CMP0022 will be removed from a future version
  of CMake.

  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.
编译提醒:OLD语言特性即将在下一个CMake版本剔除,CMake3.2版本不会出现这个问题,不影响解决方案的生成

注意
一般情况下,在qpid-cpp-1.36.0目录下创建build文件夹应用于VS解决方案生成
CMake配置如下:
Where is the source code:E:/bin/qpid-cpp-1.36.0
Where is build the binaries:E:/bin/qpid-cpp-1.36.0/build
BUILD_BINDING_DOTNET 取消编译


配置Boost依赖库环境变量

场景
 Qpid依赖Boost库,一般情况下,使用CMake生成VS解决方案的时候,需要指定Boost头文件和库文件目录,否则出现如下的错误编译提示:
Could not find the following Boost libraries:  boost_sysytem ,boost_thread 

解决方案一:
在环境变量中新建一个:名为BOOST_ROOT,值为E:\work2\boost_1_58_0

解决方案二:
在环境变量中新建一个:名为BOOST_INCLUDEDIR,值为E:\work2\boost_1_58_0
在环境变量中新建一个:名为BOOST_LIBRARYDIR,值为E:\work2\boost_1_58_0\stage\lib
重启系统,让环境变量生效
 
注意事项
1)CMake只能搜索到Boost编译的动态库,静态库编译无法搜索
2)直接从官方下的编译好的包,而编译好的包里头,库文件目录的名字是lib64-msvc-12.0,需要修改为lib或者stage/lib
FindBoost.cmake文件是如何搜索Boost lib文件的呢?
下面是搜索Boost lib的脚本代码,当然如果不修改库文件目录可以添加如下
      ${Boost_INCLUDE_DIR}/lib64-msvc-12.0
    list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c}
      ${Boost_INCLUDE_DIR}/lib
      ${Boost_INCLUDE_DIR}/../lib
      ${Boost_INCLUDE_DIR}/stage/lib
      )

3)下载Boost源码编译动态库
b2.exe  --build-type=complete --build-dir=build_tmp toolset=msvc-14.0 address-model=32 stage
说明:stage说明将编译的库文件复制到stage目录,生成过程的文件保存在build_tmp目录,toolset指定使用VS2015编译器


动态库内存泄漏测试

CMake点击Configure检测系统是否安装必须的依赖库,点击Generate生成VS2015解决方案,在
build目录下生成qpid-cpp.sln,当前编译Qpid的核心原因是Qpid Client客户端调用的DLL,出现
内存泄露,因此只需要打开examples文件夹下面的qpidc_examples.sln,进行代码的跟踪调试

qpidc_exmaples.sln配置,设置client作为启动项,
将boost库的DLL,qpidclientd.dll qpidcommond.dll qpidmessagingd.dll qpidtyped.dll还有相关的pdb文件拷贝到examples\messaging\Debug才能够调试源码
编写简单的测试程序:
int SimpleTest()
{
std::string broker = "localhost:5672";
std::string address = "amq.topic";
Connection connection(broker);
try {
connection.open();
Session session = connection.createSession();

while (1)
{
Receiver &receiver = session.createReceiver(address);
Sender &sender = session.createSender(address);
sender.send(Message("Hello world!"));

Message message = receiver.fetch(Duration::SECOND * 1);
std::cout << message.getContent() << std::endl;
session.acknowledge();
::Sleep(25);
}

session.close();
connection.close();
return -1;
}
catch (const std::exception& error) {
std::cerr << error.what() << std::endl;
connection.close();
return 0;
}
}

int main(int argc, char** argv)
{
while (1)
{
SimpleTest();
::Sleep(25);
}
return 0;
}

总结
不断的连接断开将造成内存泄露,如果保持长连接,只是进行消息的收发,就不会出现内存问题


异常以及崩溃

1)Virtual host is not active
Qpid客户端异常打印

2)internal-error: Sasl error: no common mechanism (E:\qpid-cpp-1.36.0\src\qpid\client\windows\SaslFactory.cpp:155)
Qpid调用指定的地址不正确


3)Qpid客户端崩溃信息
问题签名:
  问题事件名称:    APPCRASH
  应用程序名:    thriftserver.exe
  应用程序版本:    0.0.0.0
  应用程序时间戳:    5a55af2a
  故障模块名称:    qpidmessagingd.dll
  故障模块版本:    1.36.0.1
  故障模块时间戳:    595f3062
  异常代码:    c0000005
  异常偏移:    000d13fe
  OS 版本:    6.1.7601.2.1.0.272.7
  区域设置 ID:    2052
  其他信息 1:    0a9e
  其他信息 2:    0a9e372d3b4ad19135b953a78882e789
  其他信息 3:    0a9e
  其他信息 4:    0a9e372d3b4ad19135b953a78882e789


4)C++ 异常
boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >
qpid::types::InvalidConversion