Windows
windows平台需要先这样,要不然__declspec(dllexport)会报错。
%include <windows.i>
std::string
swig提供了很多stl的包装,能够自动和目标语言互转。需要这样写
%include "std_string.i"
std::vector
%include "std_vector.i"
namespace std {
%template(IntVector) vector<int>;
%template(DoubleVector) vector<double>;
}
因为vector是模板类,所以需要手动实例化一些模板。目标语言里面用IntVector这样的类来操作。
std::array
我编译的时候std_array.i会报错,不知什么原因。只能把代码里面的std::array替换成其他实现。
std::shared_ptr
%include "std_shared_ptr.i"
这句在我这里报错找不到std_shared_ptr.i文件。在swig目录看是在python文件夹下,所以改成这样的:
%include "python/std_shared_ptr.i"
命令行也给加了个头文件路径
-I'D:\swigwin-4.0.2\Lib\python\'
最后还得把用到智能指针的类列出来
%shared_ptr(ns::XXX);
这样智能指针就能当作普通对象在目标语言里面用了。
编译动态链接库
将生成的wrap.cxx文件和其他源码一起编译成动态链接库。 cmake里面可以这样写
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
target_link_libraries(project_name PRIVATE ${PYTHON_LIBRARIES})
在windows平台上xx.dll重命名为_xx.pyd((Linux上为_xxx.so)),编译选项需要是Release x64。 最后就可以import生成的.py文件来用了。
Node.js
SWIG支持的Node.js版本比较久,但是SWIG的master分支是支持新版v8接口的,需要自己从源码编译SWIG。
SWIG对javascrit的支持不是很完善,智能指针没有提供内建支持,所以要自己把智能指针导出给上层。例如:
namespace std {
template<typename T>
struct shared_ptr {
shared_ptr(T *ptr);
T *get() { return ptr; }
};
}
%template(XXXPtr) std::shared_ptr<XXX>;
使用node-gyp来构建。也可以去找一下node-gyp的缓存目录,找到include目标加到IDE里面自己构建。dll后缀名要改成.node才能在js中加载。
Buffer数据导出
假如需要导出的C代码:
void read(char *str, size_t size);
在python里面用bytearray,在js里面用ArrayBuffer,是最高效的。
python:
%include <pybuffer.i>
%pybuffer_mutable_binary(char *str, size_t size);
js:
%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE) {
ssize_t size = 0; void *buf = 0;
v8::Handle<v8::ArrayBuffer> view = v8::Handle<v8::ArrayBuffer>::Cast($input);
if (view.IsEmpty()) {
SWIG_exception_fail(SWIG_ArgError(SWIG_ERROR), "ArrayBuffer excepted");
}
size = view->ByteLength();
buf = view->GetContents().Data();
$1 = ($1_ltype) buf;
$2 = ($2_ltype) (size/sizeof($*1_type));
}
%enddef
%pybuffer_mutable_binary(char *str, size_t size);