在调试 Visual Studio 2008 程序时,经常有一些动态链接库(即 dll 文件)需要加载到工程里,这样才能依赖第三方库进行程序调试。

这些动态链接库,往往都是测试版本或是开发中的版本,或者会有若干个版本;这个时候,如果直接把 dll 所在目录加到 PATH 里,则会有潜在冲突的危险;如果直接拷贝到 Visual Studio 的目录下,假如测试工程太多,每次有新版本的动态链接库更新时,你需要更新若干次,拷贝、粘贴苦不堪言。

在开发过程中,究竟怎样来让 Visual Studio 链接这些 lib 及 dll 文件会比较好呢?

总体上来说,有几种方法可以改变 Visual Studio 的环境变量设置:

  1. 直接添加到系统的 PATH 变量里

    这个方法最简单,也最直接,但是坏处是会影响全局的 PATH 设置,尤其是你包含着大量测试用的 dll 时。

  2. 在 Visual Studio 全局设置里,把 dll 所在目录添加到 PATH 里:

    通过 Visual Studio 菜单 ==> 工具 ==> 选项 ==> 项目和解决方案 ==> VC++目录,在下拉框里选择"可执行文件",然后把 dll 所在路径添加进去。

  3. 直接把所有 dll 拷贝到 Visual Studio 工程目录下,或是拷贝到生成可执行文件的文件夹(默认情况下是 Debug 或 Release 目录)下:

    这个方法也很简单,但是当你有若干个工程时,你每次更新 SDK 及其 dll 文件,你就要把所有的工程都更新,这个不符合文件唯一性的工程性准则。

  4. 在调试程序时,让 Visual Studio 帮你切换当前工作目录到 dll 相应的目录下:

    在 Visual Studio ==> Project ==> Properties ==> Select Configuration ==> Configuration Properties ==> Debugging ==> Working directory 里填上 dll 所在目录,这样当在调试程序时,Visual Studio 会把当前工作目录切换到这个目录下,从而会自动读取本目录下的 dll 文件。

    这个方法的优点很明显,简单!副作用也很明显,在你切换了当前工作目录后,你可能会找不到程序的配置文件,在程序里写的诸如"./config.ini"全部都找不到了;另外,你要把所有的 dll 都放到这个工作目录里,否则一样会提示说找不到 xxx.dll 的问题。

  5. 最后一个方法,也是我认为最好的一个方法,在 Visual Studio 工程属性里把一个目录临时添加到 PATH 环境变量里:

    MSDN 上也有类似的介绍:How to: Set Environment Variables for Projects,方法很简单,在 "工程属性" ==> "调试" ==> "环境"里,添加类似如下所示的内容:

    PATH=%PATH%;$(TargetDir)\DLLS
    

    这样就可以把 $(TargetDir)\DLLS 临时添加到该工程所属的系统 PATH 里。

大家可以根据项目的实际情况,灵活选用以上方法。

注:本文撰写时参考了 StackOverflow 上的讨论话题:How do I set a path in visual studio?

posted @ 2011-10-31 15:44 Water Lin 阅读(212) 评论(0) 编辑

Emacs Org Mode 里,默认情况下 _ 这种字符会被当成标记语言来进行转义。有的时候,如果你只是写写文章,这种默认的转义,会让你很不方便,尤其是你在写一篇介绍技术的文章,里面出现的变量名有很多的下划线。这时,你会说:"Oh, my god! 难道要我一个一个去标记不让 _ 转义么?"

如何设置让 Org Mode 在默认情况下,不转义 _ 字符呢?

单个 org 文件的解决办法

你可以在一个 org 文件的开头,用下面的设置来关闭这个功能。

#+OPTIONS: ^:nil

如果你需要更方便的设置,可以把上面这个改为

#+OPTIONS: ^:{}

这样,当你写

a_{b}

时,_ 后被 {} 括起来的内容就会被转义,而写 a_b 时,就按普通的方式来显示。

org sites 的解决办法

如果你是用 org sites 来写笔记,想让某个 site 的所有 org 文件不转义 _ 字符,则也可以直接在 org sites 配置文件里,配置下面这么一句,一了百了:

(setq org-export-with-sub-superscripts nil)

也可以在 org sites 里设置这个属性,只作用于某一个 site:

:sub-superscript nil

如果需要像上面一样,采用相对智能的 {} 方式,可以设置成

:sub-superscript {}

或是直接用 elisp 来设置全局的属性:

(setq org-export-with-sub-superscripts '{})

这样就会用 {} 来转义了。

posted @ 2011-10-09 17:47 Water Lin 阅读(15) 评论(0) 编辑

最近折腾得够呛,天天写代码,都没时间更新博客了。

总结一下最近碰到的两个问题,写到中文 Wiki 里了,希望对大家有点帮助。

  1. OpenCV 在 Ubuntu 11.04 平台上的编译

    最近要迁移大把工作成果到 Linux 平台,即要在 Linux 下大量地折腾与 OpenCV 相关的代码。很久没有在 Linux 上折腾了,时过境迁,同样碰到了不少问题,写成日志《OpenCV 各种安装错误汇总》

  2. Berkeley DB 数据库的操作还是蛮有技巧的,如果需要把内存里结构比较复杂的数据写到 Berkeley DB 里,我当然拥有我的技巧,以把 IplImage 数据写入到 Berkeley DB 为例,介绍我对这一技术的理解。
posted @ 2011-09-09 21:19 Water Lin 阅读(13) 评论(0) 编辑

在 Visual Studio 2008 MFC 工程中,利用 Berkeley DB 来构建数据存储引擎时,在编译 db.h 文件时出现编译错误,错误提示内容如下:

错误    3       error C2143: 语法错误 : 缺少"}"(在"("的前面)        e:\water\berkeleydb\include\db.h        1226

微软的 MSDN 上有对 error C2143 的编译器错误进行解释,不过基本上没有太多可读性、可借鉴性,大意应该是一些宏定义、命名出错等。

最后,还是通过万能的 Google 大神找到了解答方法。错误的原因是 DB_TYPE, DB_UNKNOWN 类型已经在 MFC 系统头文件中被定义过,解决办法之一是在 db.h 中定义 DB_TYPE, DB_UNKNOWN 的语句之前加上如下语句即可:

#ifdef DB_UNKNOWN
#undef DB_UNKNOWN
#endif
#ifdef DBTYPE
#undef DBTYPE
#else
#define DBTYPE BDBTYPE
#endif

看来,C 和 C++ 混在一块,命名、类型定义真是一个大问题。以后碰到类似的问题,也可以采用类似的解决办法。

参考资料:

  1. 解决在vs2008的mfc工程中编译BerkeleyDB出错问题
  2. VS2005中的MFC程序使用BerkeleyDB
  3. MSDN Visual Studio 2010 Compiler Error C2143
posted @ 2011-09-05 17:38 Water Lin 阅读(55) 评论(0) 编辑

今天为这件事情折腾了一天!

我用 Java 写的中间件,会根据用户的需要,启动一个子进程,这个进程是用 C++ 写的,正好用到了 Log4Cxx 来记录日志以便分析。这个进程,单独从控制终端运行,没有任何问题;但是一旦用 Java 启动子进程的方式来启动,则这个子进程刚一启动就阻塞不动了,然后大概等上几十分钟到两个小时不等,该子进程则又能顺利执行下去。

第一次碰到这样的问题,很怪异,经过反复测试及万能的 Google 帮忙,找到Java调用外部程序挂起原因,Log4Cxx 原来是罪魁祸首,因为它重定向了大量的日志信息到控制台,由于 Java 进程没有清空程序写到缓冲区的内容,结果导致程序一直在等待。

解决这个问题有两个办法:

  1. 按上文中的说法,在遇到 Java 启动外部程序而导致线程阻塞的时候,可以考虑使用两个线程来同时清空 process 获取的两个输入流;
  2. 直接把 Log4Cxx 重定向到控制台的日志消息给取消掉,这个可以通过 Log4Cxx 的配置文件来实现

问题搞定了,世界又变得很美好了!

posted @ 2011-08-24 18:00 Water Lin 阅读(25) 评论(0) 编辑
摘要: 在写客户端的时候,经常要传输一些文件,有一些服务器就是用 FTP 来搭建的,这个时候,如何用客户端来发起 FTP 网络连接呢? 如果是用 MFC 来发起 FTP 文件传输请求,和使用 MFC 来发起 HTTP 请求类似,非常简单。理论基础可以仔细阅读 MSDN 上的官方文档 Steps in a Typical FTP Client Application,浏忙绪绪在这里,就贴上我自己写的代码,...阅读全文
posted @ 2011-08-22 14:45 Water Lin 阅读(33) 评论(0) 编辑
摘要: Emgu CV 是 OpenCV 跨平台的 C# 封装包,主要是为了方便在 C# 里使用 OpenCV 的库函数,下载和安装都很简单,新建一个 C# 控制窗口程序后,Hello World 例子代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst...阅读全文
posted @ 2011-08-05 16:44 Water Lin 阅读(94) 评论(0) 编辑
摘要: OpenCV2.1 生成视频选择编码的 bug 最近使用 OpenCV2.1 来生成视频,在 Windows 下碰到这样的问题:不管我用什么样的编码,都没有办法直接生成视频,并且会导致程序崩溃。代码如下: _writer = cvCreateVideoWriter( video.c_str(), CV_FOURCC('X','V','I','D'), _fps, cvSize(frameW,fr...阅读全文
posted @ 2011-08-02 17:10 Water Lin 阅读(68) 评论(0) 编辑
摘要: 在搬出大学城之前,我发现了 Netpas 的一个 Bug。 一般来讲,你用 Netpas 这种 VPN 来上网,都有一个带宽的峰值,一旦你超过这个峰值,服务器就会提示,让你注意流量或是直接把你给断开。 而 Netpas 在弹出超出流量的提示后,你不去点"确定",你还可以继续保持高流量的使用它。这个不知道是不是一个 Bug,还是在用户没有"确认"之前,Netpas 是要保护用户的权益? 不管怎么样...阅读全文
posted @ 2011-07-17 00:40 Water Lin 阅读(21) 评论(0) 编辑
摘要: 在 Linux 下,如果你写好了自己的动态链接库,需要在其它程序里调用,则需要让这些程序能找到这些动态链接库。如果设置不对,会出现类似如下的错误: test: error while loading shared libraries: libexampleso.so.0: cannot open shared object file: No such file or directory 这是因为...阅读全文
posted @ 2011-07-14 10:38 Water Lin 阅读(516) 评论(0) 编辑