警告 LNK4197:多次指定导出 'PyInit_python_module_name';使用第一个规范
warning LNK4197: export 'PyInit_python_module_name' specified multiple times; using first specification
我创建了一些 Cython
文件,并使用
将它们导入到 Python
文件中
import pyximport
pyximport.install()
import Cython_Mod1
import Cython_Mod2
当我 运行 py
文件时,C
编译器 (VC++14
) 生成以下错误
Cython_Mod1.obj : warning LNK4197: export 'PyInit_Cython_Mod1' specified multiple times; using first specification
每个 Cython
模块。
如何解决这个问题,它会影响性能还是会在执行过程中出错。
LNK4197
是一个警告,因此它不应该影响你的 .c
文件的编译,Cython
可能只是生成多次导出该函数的代码(永远原因,我假设)。
由于PyInit_<modname>
负责初始化模块;如果您的模块得到正确初始化和导入,您就没有问题。不会影响性能and/or导致错误执行。
正如@Jim 的回答所述,这只是一个(相对良性的)警告,可以忽略。
但是,此答案提供了更多信息和修复方法。
当 Python 解释器加载 extension/dll 时,模块的初始化函数(例如 PyInit_Cython_Mod1
)必须是 visible/exported.
Cython使用宏PyMODINIT_FUNC
来标记init-function,定义为
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
Py_EXPORTED_SYMBOL
在 Windows 上被标记为 visible/exported:
#define Py_EXPORTED_SYMBOL __declspec(dllexport)
因此,无需通过命令行中的链接器选项导出符号。
然而,可能由于历史原因,distutils
发挥安全作用,并通过 /EXPORT:
-链接器选项导出 init-symbol,如 here:[=26 所示=]
...
export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])]
...
export_symbols
由get_export_symbols
计算:
def get_export_symbols(self, ext):
"""Return the list of symbols that a shared extension has to
export. This either uses 'ext.export_symbols' or, if it's not
provided, "PyInit_" + module_name. Only relevant on Windows, where
the .pyd file (DLL) must export the module "PyInit_" function.
"""
initfunc_name = "PyInit_" + ext.name.split('.')[-1]
if initfunc_name not in ext.export_symbols:
ext.export_symbols.append(initfunc_name)
return ext.export_symbols
但是,因为我们不需要通过链接器选项导出任何符号,所以我们可以按如下方式覆盖此方法:
from distutils.command.build_ext import build_ext
def get_export_symbols_fixed(self, ext):
return []
# replace wrong version with the fixed:
build_ext.get_export_symbols = get_export_symbols_fixed
import pyximport
pyximport.install()
...
这次没有警告!
我创建了一些 Cython
文件,并使用
Python
文件中
import pyximport
pyximport.install()
import Cython_Mod1
import Cython_Mod2
当我 运行 py
文件时,C
编译器 (VC++14
) 生成以下错误
Cython_Mod1.obj : warning LNK4197: export 'PyInit_Cython_Mod1' specified multiple times; using first specification
每个 Cython
模块。
如何解决这个问题,它会影响性能还是会在执行过程中出错。
LNK4197
是一个警告,因此它不应该影响你的 .c
文件的编译,Cython
可能只是生成多次导出该函数的代码(永远原因,我假设)。
由于PyInit_<modname>
负责初始化模块;如果您的模块得到正确初始化和导入,您就没有问题。不会影响性能and/or导致错误执行。
正如@Jim 的回答所述,这只是一个(相对良性的)警告,可以忽略。
但是,此答案提供了更多信息和修复方法。
当 Python 解释器加载 extension/dll 时,模块的初始化函数(例如 PyInit_Cython_Mod1
)必须是 visible/exported.
Cython使用宏PyMODINIT_FUNC
来标记init-function,定义为
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
Py_EXPORTED_SYMBOL
在 Windows 上被标记为 visible/exported:
#define Py_EXPORTED_SYMBOL __declspec(dllexport)
因此,无需通过命令行中的链接器选项导出符号。
然而,可能由于历史原因,distutils
发挥安全作用,并通过 /EXPORT:
-链接器选项导出 init-symbol,如 here:[=26 所示=]
...
export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])]
...
export_symbols
由get_export_symbols
计算:
def get_export_symbols(self, ext):
"""Return the list of symbols that a shared extension has to
export. This either uses 'ext.export_symbols' or, if it's not
provided, "PyInit_" + module_name. Only relevant on Windows, where
the .pyd file (DLL) must export the module "PyInit_" function.
"""
initfunc_name = "PyInit_" + ext.name.split('.')[-1]
if initfunc_name not in ext.export_symbols:
ext.export_symbols.append(initfunc_name)
return ext.export_symbols
但是,因为我们不需要通过链接器选项导出任何符号,所以我们可以按如下方式覆盖此方法:
from distutils.command.build_ext import build_ext
def get_export_symbols_fixed(self, ext):
return []
# replace wrong version with the fixed:
build_ext.get_export_symbols = get_export_symbols_fixed
import pyximport
pyximport.install()
...
这次没有警告!