简体   繁体   English

Python C 分机:Linker 表示“符号的多重定义”

[英]Python C Extension: Linker says 'multiple definition of symbol'

I am currently working on creating a Python extension using C, which includes the definition of a custom object type.我目前正在使用 C 创建一个 Python 扩展,其中包括自定义 object 类型的定义。 In order to maintain a clear and organized codebase, I have chosen to define and implement this object in a separate file.为了保持一个清晰和有组织的代码库,我选择在一个单独的文件中定义和实现这个 object。 However, as per the Python C API, functions and objects must be defined as static.但是,根据 Python C API,函数和对象必须定义为 static。

Despite this, I have used the __attribute__((visibility("hidden"))) attribute for this object. Unfortunately, I am encountering a recurring error from the linker, specifically, "multiple definition of symbol."尽管如此,我还是为这个 object 使用了__attribute__((visibility("hidden")))属性。不幸的是,我遇到了来自 linker 的反复出现的错误,特别是“符号的多重定义”。

The code provided below is a minimal and easily replicable demonstration of the issue encountered in my larger project.下面提供的代码是我在大型项目中遇到的问题的最小且易于复制的演示。 Due to the large number of type objects present in the main project, I am seeking to organize them into separate files for improved maintainability.由于主项目中存在大量类型对象,我正在寻求将它们组织到单独的文件中以提高可维护性。

My project structure:我的项目结构:
.
├── example.c
├── include
│   ├── lcg.h
│   └── macros.h
├── lcg.c
└── setup.py
example.c例子.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "lcg.h"

static PyMethodDef example_methods[] = {
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef example_module = {
    PyModuleDef_HEAD_INIT,
    "example",
    "An example module",
    -1,
    example_methods
};

PyMODINIT_FUNC PyInit_example(void) {
    PyObject *module;

    if (PyType_Ready(&LCG) < 0)
        return NULL;

    module = PyModule_Create(&example_module);

    if (module == NULL)
        return NULL;

    Py_INCREF(&LCG);
    PyModule_AddObject(module, "LCGType", (PyObject*)&LCG);

    return module;
}
lcg.c lcg.c

SYM_PRIVATE is defined in macros.h and expands to __attribute__((visibility("hidden"))) . SYM_PRIVATEmacros.h中定义并扩展为__attribute__((visibility("hidden")))

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "structmember.h"
#include "macros.h"  /* for SYM_PRIVATE */
#include "lcg.h"

static PyObject *LCG__dummy(LCG_Type *self)
{
    int value = 10;
    return PyFloat_FromDouble(value);
}

static PyMemberDef LCG_members[] = {
    {NULL} /* sentinel */
};

static PyMethodDef LCG_methods[] = {
    {"dummy", (PyCFunction)LCG__dummy, METH_NOARGS, "A simple dummy function on LCG module."},
    {NULL} /* sentinel */
};

SYM_PRIVATE PyTypeObject LCG = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "example.LCG",
    .tp_doc = PyDoc_STR("Linear Congruential Generator"),
    .tp_basicsize = sizeof(LCG_Type),
    .tp_itemsize = 0,
    .tp_flags = Py_TPFLAGS_DEFAULT,
    .tp_members = LCG_members,
    .tp_methods = LCG_methods,
};
lcg.h lcg.h
#ifndef LCG_H
#define LCG_H

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "structmember.h"
#include "macros.h"  /* for SYM_PRIVATE */

typedef struct {
    PyObject_HEAD
    int foo;
} LCG_Type;

SYM_PRIVATE PyTypeObject LCG;

#endif /* LCG_H */
setup.py安装程序.py
from setuptools import Extension
from setuptools import setup

example_module = Extension('example', sources=['example.c', 'lcg.c'], include_dirs=['include'])

setup(name = 'example',
      version = '1.0',
      description = 'An example module',
      ext_modules = [example_module]
)

When executing python3.10 setup.py build I got:执行python3.10 setup.py build时,我得到:

running build
running build_ext
building 'example' extension
creating build
creating build/temp.linux-x86_64-cpython-310
x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -Iinclude -I/usr/include/python3.10 -c example.c -o build/temp.linux-x86_64-cpython-310/example.o
x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -Iinclude -I/usr/include/python3.10 -c lcg.c -o build/temp.linux-x86_64-cpython-310/lcg.o
creating build/lib.linux-x86_64-cpython-310
x86_64-linux-gnu-gcc -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -g -fwrapv -O2 build/temp.linux-x86_64-cpython-310/example.o build/temp.linux-x86_64-cpython-310/lcg.o -L/usr/lib/x86_64-linux-gnu -o build/lib.linux-x86_64-cpython-310/example.cpython-310-x86_64-linux-gnu.so
/usr/bin/ld: build/temp.linux-x86_64-cpython-310/lcg.o:/home/user/workspaces/python-extension-example/src/include/lcg.h:14: multiple definition of `LCG'; build/temp.linux-x86_64-cpython-310/example.o:/home/user/workspaces/python-extension-example/src/include/lcg.h:14: first defined here
collect2: error: ld returned 1 exit status
error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1

I am running gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 , GNU ld (GNU Binutils for Ubuntu) 2.38 and Python 3.10.6 .我正在运行gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 , GNU ld (GNU Binutils for Ubuntu) 2.38Python 3.10.6

In lcg.h , comment out:lcg.h中,注释掉:

// SYM_PRIVATE PyTypeObject LCG;

In example.c , add:example.c中,添加:

extern LCG;

在此处输入图像描述

Then you will build the Python module successfully.然后你将成功构建 Python 模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python C ++扩展名:符号未定义错误 - python c++ extension: symbol not defined error 在 Windows 中构建 Python C 扩展时导出符号时出错 - Error exporting symbol when building Python C Extension in Windows Python C 扩展:ImportError:未定义符号:Py_InitModule4_64 - Python C Extension: ImportError: undefined symbol: Py_InitModule4_64 Python/C++ 扩展,链接库时出现未定义符号错误 - Python/C++ Extension, Undefined symbol error when linking a library 如何更改 linker 命令以在 Python setup.py 中构建 C++ 扩展模块? - How to change the linker command for building a C++ extension module in Python setup.py? 带有python扩展的VS2015链接器错误 - VS2015 linker error with python extension Python:C++ 扩展返回多个值 - Python: C++ extension returning multiple values 获取链接器错误 LNK2001:使用 Pybind11 构建 Python 扩展时无法解析的外部符号 PyInit_your_module_name - Getting linker error LNK2001: unresolved external symbol PyInit_your_module_name when building a Python extension using Pybind11 在Python 3.6中调用C ++扩展时,导入错误“未定义符号:_ZNK9FastNoise8GetNoiseEff” - Import error “undefined symbol: _ZNK9FastNoise8GetNoiseEff” when calling C++ extension in Python 3.6 Python OpenSSL C扩展:未定义符号:AES_set_encrypt_key - Python OpenSSL C extension: undefined symbol: AES_set_encrypt_key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM