标签: python-extensions

如何在C++中有效地构建Python字典

出于性能原因,我想将部分python程序移植到C++中,因此我尝试为程序编写一个简单的扩展.C++部分将构建一个字典,然后需要将其传递给Python程序.

我发现的一种方法似乎是在C++中构建我的类似dict的对象,例如a boost::unordered_map,然后使用Py_BuildValue[1]方法将其转换为Python ,该方法能够生成Python dicts.但是这种方法包括将容器转换为字符串表示并返回看起来有点太多"即将到来"才能成为最高性能的解决方案!?

所以我的问题是:在C++中构建Python字典的最高效方法什么?我看到boost有一个Python库,它支持在C++和Python之间映射容器,但到目前为止我没有在文档中找到我需要的东西.如果有这样的方式我宁愿在C++中直接构建Python dict,那么就不需要复制等.但如果最有效的方法是另一种方式,我也很擅长.

这是(简化的)C++ - 我编译成.dll/.pyd的代码:

#include <iostream>
#include <string>
#include <Python.h>
#include "boost/unordered_map.hpp"
#include "boost/foreach.hpp"

extern "C"{
typedef boost::unordered_map<std::string, int> hashmap;

static PyObject*
_rint(PyObject* self, PyObject* args)
{
    hashmap my_hashmap; // DO I NEED THIS?
    my_hashmap["a"] = 1; // CAN I RATHER INSERT TO PYTHON DICT DIRECTLY??
    BOOST_FOREACH(hashmap::value_type i, my_hashmap) {
            // INSERT ELEMENT TO PYTHON DICT
    }
    // return PYTHON DICT
}

static PyMethodDef TestMethods[] = …
Run Code Online (Sandbox Code Playgroud)

c++ python performance dictionary python-extensions

4
推荐指数
1
解决办法
4926
查看次数

将输出文件添加到 Python 扩展

我已经定义了一个自定义build_ext来构建一个时髦的扩展,我试图使 pip 友好。以下是我正在做的修剪版本。

foo_ext = Extension(
  name='foo/_foo',
  sources=foo_sources,
)

class MyBuildExt(build_ext):
  def build_extension(self, ext):
    # This standalone script builds the __init__.py file 
    #  and some .h files for the extension
    check_call(['python', 'build_init_file.py'])

    # Now that we've created all the init and .h code
    #  build the C/C++ extension using setuptools/distutils
    build_ext.build_extension(self, ext)

    # Include the generated __init__.py in the build directory 
    #  which is something like `build/lib.linux-x86/foo/`.  
    #  How can I get setuptools/distutils to install the 
    #  generated …
Run Code Online (Sandbox Code Playgroud)

python distutils pip setuptools python-extensions

4
推荐指数
1
解决办法
1139
查看次数

如何从 C 的 PyObject 类型的函数将值从 C 返回到 python?

我试图通过从 python 调用 C 文件来传递一个值,然后再次将该值从 C 返回到 python。

我的问题是如何做到这一点?可以使用返回Py_BuildValue(a+b)类型的东西吗?

#include <Python.h>

static PyObject *
hello_world(PyObject *self, PyObject *noargs)
{
   int a=5,b=10;

   return Py_BuildValue(a+b); //This is Errorus.
}


static PyMethodDef
module_functions[] = {
    { "hello_world", hello_world, METH_NOARGS, "hello world method" },
    { NULL }
};



PyMODINIT_FUNC
inittesty2(void)
{
    Py_InitModule("testy2", module_functions);
}
Run Code Online (Sandbox Code Playgroud)

c python python-c-api python-c-extension python-extensions

4
推荐指数
1
解决办法
2164
查看次数

tp_clear,tp_dealloc和tp_free有什么区别?

我有一个用于模糊字符串搜索的自定义python模块,实现了Levenshtein距离计算,它包含一个称为levtree的python类型,它具有两个成员,该指针指向执行所有计算的wlevtree C类型(称为tree)的指针和指向的PyObject * python字符串的python列表,称为wordlist。这是我需要的:

-当我创建levtree的新实例时,我使用一个构造函数,该构造函数将字符串元组作为其唯一输入(并且该字典将在其中实例执行所有搜索),该构造函数将必须创建levtree的新实例。将wordlist添加到levtree的新实例中,然后将输入元组的内容复制到wordlist的新实例中。这是我的第一个代码段和第一个问题:

static int
wlevtree_python_init(wlevtree_wlevtree_obj *self, PyObject *args, PyObject *kwds)
{
    int numLines;       /* how many lines we passed for parsing */
    wchar_t** carg;        /* argument to pass to the C function*/
    unsigned i;

    PyObject * strObj;  /* one string in the list */
    PyObject* intuple;

    /* the O! parses for a Python object (listObj) checked
      to be of type PyList_Type */
    if (!(PyArg_ParseTuple(args, "O!", &PyTuple_Type, &intuple)))
    {
        return -1;
    }

    /* get the number of lines …
Run Code Online (Sandbox Code Playgroud)

c python python-extensions

3
推荐指数
1
解决办法
1076
查看次数

无法为 c++ python 扩展编译 swig 生成的包装器

嗨,我正在尝试使用 C++ 中的 swig python 扩展,例如 -在 Mit 页面上

我的标题是-shapes.h

#include <iostream>

class Shape
{
    public:
    Shape()
    {
        nshapes++;
    }
    ~Shape()
    {
        nshapes--;
    }
    double  x, y;   
    void    move(double dx, double dy);
    virtual double area() = 0;  
    virtual double perimeter() = 0;
    static  int nshapes;
};

class Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area();
  virtual double perimeter();
};

class Square : public Shape {
private:
  double width;
public: …
Run Code Online (Sandbox Code Playgroud)

c++ python swig python-extensions sdn

3
推荐指数
1
解决办法
3878
查看次数

如何在包装 C++ 代码的 SWIG 中向目标语言(特别是 Python)添加替代构造函数

我正在使用 SWIG 创建一些我无法更改的 C++ 代码的 Python 接口。其中一个 C++ 类有一个构造函数,该构造函数创建一个尚未使用的部分初始化的对象,必须首先对其调用初始化函数。我想在 Python 中通过提供一个替代构造函数来解决这个问题,该构造函数可以同时完成两件事(获取和初始化)。假设在 C++ 中我有

class X {
 public:
  X() {...}
  void init(T a) {...}
  ...
};
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,我必须将 X 实例化为

X x;
x.init(a);
Run Code Online (Sandbox Code Playgroud)

在Python中我想做

x = X(a)
Run Code Online (Sandbox Code Playgroud)

我的解决方案是一个 hack,取决于目标语言和 SWIG 生成包装器代码的具体方式:在我的 .i 文件中,我有

%inline %{
X* new_X(T a) {
  X* ret = new X();
  ret->init(a);
  return ret;
}

%nodefaultctor X;
class X {
 public:
  ...
  %extend {
    %pythoncode {
      def __init__(self, *args):
          this = _modulename.new_X(*args)
          try:
            self.this.append(this)
          except:
            self.this = …
Run Code Online (Sandbox Code Playgroud)

c++ python swig python-extensions

3
推荐指数
1
解决办法
2042
查看次数

C python扩展中的分段错误

我正在为python3.7写一个C扩展模块。我有一个简单的结构作为PyObject:

typedef struct {
    PyObject_HEAD
    double attacker;
    double victim;
    double game_hardness;
    int inflation;
} RatingSystem;
Run Code Online (Sandbox Code Playgroud)

和初始化器:

static int 
RatingSystem_init(RatingSystem *self, PyObject *args, PyObject *kwargs) {
    double kek;
    static char *kwargs_list[] = {"attacker", "victim", "game_hardness", "inflation"};
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$dddi", kwargs_list,
                                      &self->attacker, &self->victim,
                                      &self->game_hardness, &self->inflation)) {
        return -1;
    }

    printf("Success\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我在python 3.7.3下的Mac OS上运行它,一切正常,但是如果我切换到alpine 3.10 python docker image(python:3.7-alpine),请执行以下初始化:

import rating_system
rs = rating_system.RatingSystem(attacker=1000.0, victim=1000.0, game_hardness=1300.0, inflation=1)
Run Code Online (Sandbox Code Playgroud)

我懂了Segmentation fault。在gdb下运行显示以下内容:

Program received signal SIGSEGV, Segmentation fault.
vgetargskeywords (args=0x7f87284f0050, kwargs=0x7f87284e0a00, …
Run Code Online (Sandbox Code Playgroud)

c python python-extensions docker alpine-linux

3
推荐指数
1
解决办法
70
查看次数

安装python扩展时出错“无法打开文件‘目录+文件名’:[错误2]没有这样的文件或目录”

我试图在 vs 代码中安装 mypy 扩展,但它一直在下面显示这个错误

C:\Users\Yourusername\Dev\django_project_boilerplate\env\Scripts\python.exe: can't open file 'c:UsersYourusername.vscodeextensionsms-python.python-2020.6.89148pythonFilespyvsc-run-isolated.py': [Errno 2] No such file or directory
(env)
Run Code Online (Sandbox Code Playgroud)

然后我意识到终端正在从下面命令的文件位置中删除反斜杠,因为它是一个特殊字符

c:/Users/Yourusername/Dev/django_project_boilerplate/env/Scripts/python.exe c:\Users\Yourusername\.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\pyvsc-run-isolated.py pip install -U mypy 
Run Code Online (Sandbox Code Playgroud)

terminal python-extensions visual-studio-code

3
推荐指数
2
解决办法
2319
查看次数

包含和分发带有 Python C 扩展的第三方库

我正在构建一个使用“第三方”库的 C Python 扩展——在本例中,我使用单独的构建过程和工具链构建了一个。调用这个库libplumbus.dylib

目录结构为:

grumbo/
  include/
    plumbus.h
  lib/
    libplumbus.so
  grumbo.c
  setup.py
Run Code Online (Sandbox Code Playgroud)

我的setup.py样子大约是:

from setuptools import Extension, setup

native_module = Extension(
    'grumbo',
    define_macros = [('MAJOR_VERSION', '1'),
                     ('MINOR_VERSION', '0')],
    sources       = ['grumbo.c'],
    include_dirs  = ['include'],
    libraries     = ['plumbus'],
    library_dirs  = ['lib'])


setup(
    name = 'grumbo',
    version = '1.0',
    ext_modules = [native_module] )
Run Code Online (Sandbox Code Playgroud)

由于 libplumbus 是一个外部库,当我运行时,import grumbo我得到:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/path/to/grumbo/grumbo.cpython-37m-darwin.so, 2): Library not loaded: lib/libplumbus.dylib
  Referenced …
Run Code Online (Sandbox Code Playgroud)

c python setuptools python-c-api python-extensions

3
推荐指数
1
解决办法
717
查看次数

在Windows中构建Python C扩展时导出符号时出错

我正在努力将Python模块移植到Windows.我有一个玩具示例如下.

文件夹结构是:

foo/
  libfoo/
    foo.c
  setup.py
Run Code Online (Sandbox Code Playgroud)

setup.py

from setuptools import setup, Extension

sources = ['libfoo/foo.c']

foo = Extension('libfoo',
                 sources = sources,
                 define_macros = None,
                 include_dirs = ['./libfoo'],
                 libraries = None,
                 library_dirs = None,
                 )

setup(name          = 'foo',
      ext_modules      = [foo],
      install_requires = ['setuptools'],
)
Run Code Online (Sandbox Code Playgroud)

libfoo/foo.c(完整性)

#include <stdio.h>

void foo() {
  printf("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)

当我尝试安装包时,遇到错误.

C:\Users\user\foo>python setup.py install
running install
running bdist_egg
running egg_info
creating foo.egg-info
writing requirements to foo.egg-info\requires.txt
writing foo.egg-info\PKG-INFO
writing top-level names to foo.egg-info\top_level.txt
writing dependency_links to …
Run Code Online (Sandbox Code Playgroud)

python windows linker setuptools python-extensions

2
推荐指数
1
解决办法
1167
查看次数

如何使用PyList返回Python C API扩展中的整数列表?

我正在.pyd使用Visual Studio 2015 C ++项目和Python 2.7 32位构建Python扩展()。

这是我的.cpp文件:

#include <Python.h>

static PyObject* GetTwoInts(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int random1 = rand() % 10;
    int random2 = rand() % 10;

    PyObject * python_val = Py_BuildValue("ii", random1, random2);
    return python_val;
}

static PyObject* GetListTwoInts(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int random1 = rand() % 10;
    int random2 = rand() % 10;

    PyObject *val1 = PyInt_FromLong(random1);
    PyObject *val2 = PyInt_FromLong(random2);

    PyObject *result = PyList_New(2);
    PyList_SetItem(result, 0, val1);
    PyList_SetItem(result, …
Run Code Online (Sandbox Code Playgroud)

c++ python cpython python-c-api python-extensions

2
推荐指数
1
解决办法
1676
查看次数

如何编写setup.py来安装SWIG构建的python扩展(xxx.so文件)?

distutils使用SWIG构建python扩展(xxx.so)更容易 。您无需编写wrap.c程序即可包装原始的c程序。所以我想使用SWIG而不是Distutils。但是没有方法可以通过编写setup.py文件来自动安装扩展名(xxx.so)。这困扰了我很多天。

为了更清楚地解释这个问题,我使用“逐步”策略将其弄清楚。

步骤1?有一个原始的C / C ++代码。然后使用SWIG创建Python包装器。

步骤2:使用Distuils(编写setup.py)或仅使用gcc命令行创建Python扩展文件。Python扩展名是xxx.so。显然,在此步骤中,您可以使用Distuils将编译和安装结合在一起。

步骤3:通过编写setup.py安装xxx.so Python扩展。

我只是不知道STEP 3如何编写setup.py以安装xxx.so Python扩展。

是否可以通过编写setup.py而不使用sys.path.append()或sys.path.insert()方法来安装python扩展(xxx.so)?

非常感谢您提供的任何答案!

最后,我尝试了将编译和安装结合在一起的STEP 2方法。它可以正常工作,但是使用setup.py仅安装_xxx.so Python扩展并不是我的目的。

目录结构:

setup.py
src/
    libdemo/
        __init__.py
        LibHello.py
lib/
    palindrome.c   # original C code
    palindrome_wrap.c  # Python wrapper built by SWIG
Run Code Online (Sandbox Code Playgroud)

setup.py代码:

#-*- coding:utf-8 -*-
import sys
import os
from setuptools import setup, find_packages, Extension

libPath = "lib"

moduleLibPalindrome = Extension(
      name = 'libdemo._palindrome', 
      sources = [os.path.join(libPath, 'palindrome_wrap.c'), 
            os.path.join(libPath, 'palindrome.c')]
)
setup (
      name = 'test_example',
      version = '0.1',
      author = "Hobart", …
Run Code Online (Sandbox Code Playgroud)

python swig setup.py python-extensions

1
推荐指数
1
解决办法
3937
查看次数

如何在纯asm中编写python扩展并且它是否有效?

我有中等的业余技能,Python而且我是初学者,asm并且对C语言没有任何了解.

我知道python C-extensions必须遵循特定的接口才能正常工作.

是否可以Assembly使用正确的界面和完整功能编写纯粹的python扩展?第二个问题是,如果这样做的话,它是否足够有效?

谷歌搜索时,我没有找到任何关于这个问题的代码或一些文章或解决方案的例子.

不是关于asm从内部运行代码的问题Python所以它不是关于SO的主题的重复.

python assembly python-extensions

0
推荐指数
1
解决办法
968
查看次数