SWIG踩坑记

原创
2022/03/23 16:43
阅读数 361

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);
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部