在几个cython模块上共享全局c变量

时间:2018-05-15 10:05:14

标签: c cython wrapper

我想包装一个动态链接的c库,所有cython模块都链接在一起。问题是我遇到了分段错误。我读到通过extern语句向cython公开的变量对于每个模块都不相同。例如,您无法在一个模块中操作int并在另一个模块中查看更改的int。 我认为这是我的分段错误的原因。

这是我的真实世界的例子:

https://bitbucket.org/stueker/jrtk/src/master/下获取jrtk回购。 我链接到使用以下终端命令构建项目时创建的库:

GAC

我将以下文件放在回购邮件旁边的文件夹中。

setup.py

WMI

的CMakeLists.txt

mkdir build
cmake ..
make

itfMain.pyx from distutils.core import setup from Cython.Build import cythonize from distutils.extension import Extension import os import shutil import subprocess import sys def find_tcl(): build_path = "build" try: os.mkdir(build_path) except FileExistsError: print("build already exists") cmake_cache = "CMakeCache.txt" tcl_include = "TCL_INCLUDE_PATH" separator = ":PATH=" if sys.platform.startswith('win'): shell = True else: shell = False cmake_cmd = ["cmake", ".."] print("################### Calling CMAKE ###################") retCode = subprocess.check_call(cmake_cmd, cwd=build_path, stderr=subprocess.STDOUT, shell=shell) print("################### CMAKE returned ###################") text = open(os.path.join(build_path, cmake_cache)).read() start = text.find(tcl_include) include_path = text[start:text.find(os.linesep, start)] return include_path.replace(tcl_include, "").replace(separator, "").strip() jrtk_root = "/home/simon/janus/jrtk" def declare_cython_extensions(source_path): libs = ["janus"] lib_dirs = [jrtk_root + os.path.sep + "build"] postfix = "/include" base_dir = jrtk_root + os.path.sep + "source" (path, dirs, _) = next(os.walk(base_dir)) include_dirs = [os.path.join(path, d) + postfix for d in dirs] include_dirs.extend([base_dir, find_tcl()]) extension_list = [] for (path, folders, files) in os.walk(source_path): for f in files: if f.endswith(".pyx"): ext = Extension(f.replace(".pyx", ""), [os.path.join(path, f)], libraries=libs, library_dirs=lib_dirs, include_dirs=include_dirs, define_macros=[("DISABLE_TK", None), ("DISABLE_READLINE", None), # In TCL8.6 deprecated and needs this flag to activate ("USE_INTERP_ERRORLINE", None)] ) extension_list.append(ext) return extension_list extensions = declare_cython_extensions(".") ext_modules = cythonize(extensions) setup( name='Global setup', ext_modules=ext_modules ) 是结构,cmake_minimum_required( VERSION 3.5 ) project( JRTK_CYTHON ) set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake ) set ( INCLUDE_DIRECTORIES "") find_package(TCL 8.5 REQUIRED) list(APPEND INCLUDE_DIRECTORIES "${TCL_INCLUDE_PATH}") 是指向这种结构的全局指针。

Tcl_Interp

itf.pyx

interp

c_itfMain.pxd

from c_itfMain cimport Tcl_Interp, Itf_Lib_Init, interp, ClientData

cdef extern from "../jrtk/source/itf/include/itf/itf.h":
    ctypedef struct TypeInfo:
        pass

cdef extern from "../jrtk/source/itf/source/itf.c":
     cdef int itfCreate(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])


cdef extern from "../jrtk/source/models/source/tags.c":
    TypeInfo tagsInfo


def jrtk_Init():
    rv = Itf_Lib_Init(0, NULL)

def tagsTest():
    print("Hello")
    print(interp.errorLine)
    rv = itfCreate(&tagsInfo, interp, 2, ["Tags", "tagTest"])

我通过以下方式编译此cython代码:from c_itfMain cimport Itf_Lib_Init def jrtk_Init(): rv = Itf_Lib_Init(0, NULL)

test.py

cdef extern from "../jrtk/source/itf/source/itfMain.c":
    cdef int Itf_Lib_Init(int argc, char ** argv)
    cdef Tcl_Interp *interp

cdef extern from "../jrtk/source/itf/include/itf/itf.h":
    ctypedef void*ClientData

cdef extern from "/usr/include/tcl.h":
    cdef struct Tcl_Interp:
        char *result
        void (*freeProc)(char *blockPtr)
        int errorLine

此脚本将失败并显示以下输出:

python3 setup.py build_ext --inplace

如果您将import itfMain import itf itf.jrtk_Init() itfMain.tagsTest() 更改为# =========================================================================== # ____ ____ _____ _ # |__ || _ \|_ _| | # | || |_| | | | | |/ | V6.0.0, n/a # | || _ < | | | < ------------------------------------------------ # | ||_| |_| |_| |_|\_| Karlsruhe Institute of Technology, Germany # _| | JANUS Recognition Carnegie Mellon University, USA # \__/ Toolkit # (c) 1993-2017 # =========================================================================== started library: on desktop.3573, Di 15. Mai 21:18:24 CEST 2018 Janus Binary: using lib: ./lib using lib: /home/simon/janus/janus_lt/gui-tcl using lib: /home/simon/janus/janus_lt/tcl-lib using lib: /usr/lib using lib: /usr/lib/tcltk using lib: /usr/lib/tcltk/tcl8.6 using lib: /usr/lib/tcltk/x86_64-linux-gnu using lib: /usr/local/lib/tcltk using lib: /usr/local/share/tcltk using lib: /usr/share/tcltk using lib: /usr/share/tcltk/tcl8.6 using env: TCL_LIBRARY=/usr/lib/tcl8.6 using env: JANUS_LIBRARY=/home/simon/janus/jrtk/library INFO : Using doParallelServer function INFO : This machine (desktop) is running Linux 4.13.0-41-generic (x86_64) with Tcl 8.6 executing library # ============================= {Main Program} ============================== Hello Segmentation fault (core dumped) ,则不会发生分段错误。 在我的脑海中有这个c lib,它的函数和全局变量都具有来自每个模块的相同值。如果一个模块触发对一个var的更改,则所有模块都会知道。我不得不对这个假设做错,但是发生了什么以及如何解决/解决它?

小问题。 pxd文件中的itf.jrtk_Init()itfMain.jrtk_Init()之间是否存在差异?

我认为我有一个类似于这个人(https://groups.google.com/forum/#!topic/cython-users/GAAPYb2X304)的类似问题,但我已经有一个动态链接的库。

0 个答案:

没有答案