个人博客:Sekyoro的博客小屋
个人网站:Proanimer的个人网站
当项目比较大涉及到多门编程语言时会有这种需求.通常是要求调用C/C++等.
某些语言之间相对来说调用就比较简单,比如Go和C,Rust和C等,这几个语言之间互相调用就很方便.但是其他语言相对来说就麻烦了.本文主要涉及Python,JS,Java和C/C+的互相调用,以备不时之需.
TL;DR:Python使用pybind11,JS使用emcc,Java使用JNI.
Python和C或Cpp
Python调用C/Cpp
Ctypes
ctypes 是Python的外部函数库。它提供了与 C语言兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装
写一个c文件
// func.c
int func(int a){
return a*a;
}
编译成动态库
gcc func.c -fPIC -shared -std=c99 -o func.so
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
得到动态库后就能直接调用了,注意在windows上(其实指的是使用MSVC生成dll)需要使用ctypes.WinDLL
import ctypes
from ctypes import cdll
if __name__ == "__main__":
f = cdll.LoadLibrary("./func.so")
print(f.func(99))
这种方法缺点是是能调用一些已有的动态库,且不涉及复杂数据结构,只能是c语言.
C/C++扩展Python
使用Python.h头文件
#include <Python.h>
#if PY_MAJOR_VERSION >= 3
#define PyInt_Check PyLong_Check
#define PyInt_AsLong PyLong_AsLong
#endif
static PyObject* list_sum(PyObject *self, PyObject *args)
{
PyObject *pList;
PyObject *pItem;
Py_ssize_t n = 0;
int result = 0;
if(!PyArg_ParseTuple(args, "O!", &PyList_Type, &pList))
{
return NULL;
}
n = PyList_Size(pList);
for (int i=0; i<n; i++) {
pItem = PyList_GetItem(pList, i);
if(!PyInt_Check(pItem)) {
PyErr_SetString(PyExc_TypeError, "list items must be integers.");
return NULL;
}
result += PyInt_AsLong(pItem);
}
return Py_BuildValue("i", result);
}
static PyMethodDef methods[] = {
{
"sum", (PyCFunction)list_sum, METH_VARARGS, "sum method" },
{
<


2万+

被折叠的 条评论
为什么被折叠?



