【问题标题】:Python in C++: Unresolved externalC++ 中的 Python:未解决的外部问题
【发布时间】:2013-08-07 18:55:55
【问题描述】:

我尝试在我的 C++ 应用程序中嵌入 Python,但链接器一直提示此错误:

[ILINK32 Error] Error: Unresolved external '_PyModule_Create2TraceRefs' referenced from E:\CPP PROJECTS\ANDERLICHT\WIN32\DEBUG\ANDERLICHT.OBJ

我使用的是 Embarcadero C++ Builder XE2,所以我用 coff2omf.exe 转换了 python33.lib。

这是我在 main.cpp 中的代码:

#include "anderlicht.c"
#pragma comment(lib, "python33_omf.lib")

// In main():
PyImport_AppendInittab("anderlicht",PyInit_anderlicht);
Py_SetProgramName(programName.w_str());
Py_Initialize();

在 anderlicht.c 中包含 Python.h。我该怎么做才能修复此错误?

【问题讨论】:

  • 您需要向我们提供更多信息:您从哪里获得 python33.dll、python33.lib 和 python.h?如果你自己建造它们,你是如何建造它们的?您的项目的编译和链接设置是什么?

标签: c++ python embedding


【解决方案1】:

我遇到了同样的问题,但我找到了不需要重建的解决方案。

如果您正在开发一个新的应用程序,您将处于调试模式:编译器定义_DEBUG。在文件“pyconfig.h”(python 3.6.3 的第 336 行附近)中,您可以找到:

#ifdef _DEBUG
#define Py_DEBUG
#endif

=> 删除此代码。

如果您离开该代码,您将处于 Py_Debug 模式,因此在 object.h 中会触发:

#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif

在 modsupport.h 中定义了这个别名:

#ifdef Py_TRACE_REFS
 /* When we are tracing reference counts, rename module creation functions so
    modules compiled with incompatible settings will generate a
    link-time error. */
 #define PyModule_Create2 PyModule_Create2TraceRefs
 #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs
#endif

所以你的编译器需要一个自定义版本的 Python。

现在享受您的标准嵌入式 python。

【讨论】:

    【解决方案2】:

    问题很可能是您在构建代码时使用的编译器标志与构建 Python DLL 时使用的编译器标志不同。特别是,PyModule_Create2TraceRefs 仅在您有 -DPy_TRACE_REFS 时才定义(通常在 Unix 上的 make 命令中通过 EXTRA_CFLAGS 传递;我不知道您如何在 Windows 上使用 Embarcadero C++ Builder 来实现)。通常,这是没有定义的——特别是,如果您使用的是来自预构建 Python 二进制文件的 DLL,则不会对其进行定义。

    因此,如果您想在构建代码时使用自定义标志,则需要使用相同的标志重新构建 Python 本身。否则,您需要获取用于构建 Python 的标志,并在构建代码时使用相同的标志。

    在 Unix 上,这很简单:只需调用 python3.3-config --cflagspython3.3-config --ldflags 以获取传递给编译和链接步骤的标志。在 Windows 上,它不那么微不足道。文档中的Building C and C++ Extensions on Windows 章节解释了当您使用用于构建 Python 本身(通常是 MSVC)的相同工具链时如何执行此操作,并且如果您使用 mingw 及其 MSVC-compat 功能,则在其他地方有文档说明如何这样做……但是如果您使用的是不同的工具链,则需要自己解决一些问题。

    【讨论】:

      最近更新 更多