1.C++头文件中导出符号宏
关于SWIG使用过程中,有时C++头文件有导出符号,这在WINDOW系统下是很常见的事,经常看到下面的宏定义:
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
# if defined( OSG_LIBRARY_STATIC )
# define OSG_EXPORT
# elif defined( OSG_LIBRARY )
# define OSG_EXPORT __declspec(dllexport)
# else
# define OSG_EXPORT __declspec(dllimport)
# endif
#else
# define OSG_EXPORT
#endif
在用SWIG生成包装文件 XX_wrap.cxx 时,有这个导出宏会异常退出。找了很久也没有办法,网上说不支持。就这样一个动态库有两份源码?这不是程序员做的事。
翻看了OSG的一个转换工程,终于知道,重定义一下导出宏就OK了。
但是不能用#define,要用SWIG的增强宏:
%define OSG_EXPORT
%enddef
在此记录一下,希望可以帮助你少走点路。
2.SWIG宏
顺便看一下SWIG的这个%define有什么高明之处。
以下为译文:
SWIG 提供了增强宏功能,以 %define 和 %enddef 指示. 示例如下:
%define ARRAYHELPER(type,name)
%inline %{
type *new_ ## name (int nitems) {
return (type *) malloc(sizeof(type)*nitems);
}
void delete_ ## name(type *t) {
free(t);
}
type name ## _get(type *t, int index) {
return t[index];
}
void name ## _set(type *t, int index, type val) {
t[index] = val;
}
%}
%enddef
ARRAYHELPER(int, IntArray)
ARRAYHELPER(double, DoubleArray)
%define最开始是为了定义一个大的代码块。但是不像C预处理宏那样,每一行需要用(\)
结尾,但是需要用第一个碰到的%enddef来结束宏定义。此外,当这样的宏被扩展时,它们通过C预处理器进行重新分析。因此,SWIG宏可以包含所有除嵌套的%define以外的其他预处理器指令定义语句。
SWIG宏能力是产生大量代码的一种非常快速和简单的方法。事实上,很SWIG的高级特征和库都是使用此机制(如C++模板支持)构建的。
参考: