深圳公明网站建设公司,开利网络企业网站建设第一品牌,软件开发的流程,宿迁市建设局网站首页前面我们用swig封装了c的代码给java使用#xff1a;
如何用SWIG封装c接口给java使用#xff1f;-CSDN博客 但是由于我们的代码写的太好了#xff0c;python用户也想用#xff0c;我们需要将c代码封装一下给python用户使用。
这种需求很常见吧。
现在AI动不动就是用pytho…前面我们用swig封装了c的代码给java使用
如何用SWIG封装c接口给java使用-CSDN博客 但是由于我们的代码写的太好了python用户也想用我们需要将c代码封装一下给python用户使用。
这种需求很常见吧。
现在AI动不动就是用python进行训练但是有些需要提高运行速度的时候还是需要用C/C进行编写。 python与c进行交互的方式好像挺多的。
ctypepybind11但这里我们还是使用swig。 代码还是使用我们在java那里的例子。
让我们看看我们优秀的代码是怎么给python程序员带来震撼的。
apple.h
#ifndef __APPLE_H__
#define __APPLE_H__enum class LogLevel {Trace /// Most detailed output,Debug,Info,Warn,Error,Fatal /// Least detailed output,Current /// no-op, value indicates current level should be retained
};class Apple
{
public:Apple();int GetColor(void);void SetColor(int color);private:int m_nColor;
};
#endif
apple.cpp
#include apple.hApple::Apple() : m_nColor(0)
{
}void Apple::SetColor(int color)
{m_nColor color;
}int Apple::GetColor(void)
{return m_nColor;
}
我们在这两个文件里面定义了一个类Apple,给它添加了两个成员函数Setcolor和GetColor是不是非常合理一般的C都是这么写的。 写swig接口文件 apple.i
%module demo
%{
/* Includes the header in the wrapper code */
#include apple.h
%}/* Parse the header file to generate wrappers */
%include apple.h
用swig生成中间代码
swig -python -c apple.i
生成了 demo.py和 apple_wrap.cxx 两个文件
编译一下这个 cxx文件生成 _demo.so
g -g -c apple.cpp -o apple.o
g -fpic -shared apple_wrap.cxx -o _demo.so -I/usr/include/python3.8 apple.o 用python调用一下试试。
main.py import demo;a demo.Apple();
a.SetColor(2);
print(a.GetColor());
运行之
ppdell:~/wrapper$ python3 main.py
2
非常好
我们来看一下swig给我们生成的中间文件都有什么内容。 apple_wrap.cxx 的内容
文件总共3804行我们只看比较核心的部分函数的实现。
SWIGINTERN PyObject *_wrap_Apple_SetColor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {PyObject *resultobj 0;Apple *arg1 (Apple *) 0 ;int arg2 ;void *argp1 0 ;int res1 0 ;int val2 ;int ecode2 0 ;PyObject *swig_obj[2] ;if (!SWIG_Python_UnpackTuple(args, Apple_SetColor, 2, 2, swig_obj)) SWIG_fail;res1 SWIG_ConvertPtr(swig_obj[0], argp1,SWIGTYPE_p_Apple, 0 | 0 );if (!SWIG_IsOK(res1)) {SWIG_exception_fail(SWIG_ArgError(res1), in method Apple_SetColor , argument 1 of type Apple *); }arg1 reinterpret_cast Apple * (argp1);ecode2 SWIG_AsVal_int(swig_obj[1], val2);if (!SWIG_IsOK(ecode2)) {SWIG_exception_fail(SWIG_ArgError(ecode2), in method Apple_SetColor , argument 2 of type int);} arg2 static_cast int (val2);(arg1)-SetColor(arg2);resultobj SWIG_Py_Void();return resultobj;
fail:return NULL;
}SWIGINTERN PyObject *Apple_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {PyObject *obj;if (!SWIG_Python_UnpackTuple(args, swigregister, 1, 1, obj)) return NULL;SWIG_TypeNewClientData(SWIGTYPE_p_Apple, SWIG_NewClientData(obj));return SWIG_Py_Void();
}SWIGINTERN PyObject *Apple_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {return SWIG_Python_InitShadowInstance(args);
}static PyMethodDef SwigMethods[] {{ SWIG_PyInstanceMethod_New, SWIG_PyInstanceMethod_New, METH_O, NULL},{ new_Apple, _wrap_new_Apple, METH_NOARGS, NULL},{ Apple_GetColor, _wrap_Apple_GetColor, METH_O, NULL},{ Apple_SetColor, _wrap_Apple_SetColor, METH_VARARGS, NULL},{ delete_Apple, _wrap_delete_Apple, METH_O, NULL},{ Apple_swigregister, Apple_swigregister, METH_O, NULL},{ Apple_swiginit, Apple_swiginit, METH_VARARGS, NULL},{ NULL, NULL, 0, NULL }
};static PyMethodDef SwigMethods_proxydocs[] {{ NULL, NULL, 0, NULL }
};demo.py的内容就比较简单了只有90行
基本上 就是一个封装和函数调用转发。
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.1
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.from sys import version_info as _swig_python_version_info
if _swig_python_version_info (2, 7, 0):raise RuntimeError(Python 2.7 or later required)# Import the low-level C/C module
if __package__ or . in __name__:from . import _demo
else:import _demotry:import builtins as __builtin__
except ImportError:import __builtin__def _swig_repr(self):try:strthis proxy of self.this.__repr__()except __builtin__.Exception:strthis return %s.%s; %s % (self.__class__.__module__, self.__class__.__name__, strthis,)def _swig_setattr_nondynamic_instance_variable(set):def set_instance_attr(self, name, value):if name thisown:self.this.own(value)elif name this:set(self, name, value)elif hasattr(self, name) and isinstance(getattr(type(self), name), property):set(self, name, value)else:raise AttributeError(You cannot add instance attributes to %s % self)return set_instance_attrdef _swig_setattr_nondynamic_class_variable(set):def set_class_attr(cls, name, value):if hasattr(cls, name) and not isinstance(getattr(cls, name), property):set(cls, name, value)else:raise AttributeError(You cannot add class attributes to %s % cls)return set_class_attrdef _swig_add_metaclass(metaclass):Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclassdef wrapper(cls):return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())return wrapperclass _SwigNonDynamicMeta(type):Meta class to enforce nondynamic attributes (no new attributes) for a class__setattr__ _swig_setattr_nondynamic_class_variable(type.__setattr__)LogLevel_Trace _demo.LogLevel_Trace
LogLevel_Debug _demo.LogLevel_Debug
LogLevel_Info _demo.LogLevel_Info
LogLevel_Warn _demo.LogLevel_Warn
LogLevel_Error _demo.LogLevel_Error
LogLevel_Fatal _demo.LogLevel_Fatal
LogLevel_Current _demo.LogLevel_Current
class Apple(object):thisown property(lambda x: x.this.own(), lambda x, v: x.this.own(v), docThe membership flag)__repr__ _swig_reprdef __init__(self):_demo.Apple_swiginit(self, _demo.new_Apple())def GetColor(self):return _demo.Apple_GetColor(self)def SetColor(self, color):return _demo.Apple_SetColor(self, color)__swig_destroy__ _demo.delete_Apple# Register Apple in _demo:
_demo.Apple_swigregister(Apple) 可以说速度是非常的快。完全不用手动写多余的代码。
调用也非常简单推荐使用SWIG。