2

我的 Mac 上有一个使用非标准库(在我的情况下是 OpenCV 库)的 c++ 代码,需要对其进行编译,以便可以从其他计算机(至少从其他 Mac 计算机)调用它。从 python 运行。所以我有3个基本问题:

  1. 如何编译我的项目以便它可以从 python 中使用?我已经读过我应该创建一个 *.so 文件,但如何做呢?
  2. 它应该像 lib 一样工作,所以 python 调用一些特定的函数,在 python 级别选择?
  3. 还是应该包含从命令行执行的主要功能?

关于如何做到这一点的任何想法?PS:我正在使用 Eclipse IDE 编译我的 c++ 项目。

干杯,

4

5 回答 5

2

如何编译我的项目以便它可以从 python 中使用?我已经读过我应该创建一个 *.so 文件,但如何做呢?

这取决于你的编译器。以 g++ 为例: g++ -shared -o myLib.so myObject.o

它应该像 lib 一样工作,所以 python 调用一些特定的函数,在 python 级别选择?

是的,在我看来。这似乎确实是一种“显而易见”的方式,因为它对于 C++ 代码的模块化和进化非常有用。

于 2013-08-20T18:45:00.120 回答
2

如果您使用 linux,atmaere 和 nouney 的答案可能对您有用。

就我而言,当我使用 MacOSX 时,我想出了使用 cython 库的方法。下面描述了一个简单的教程来使事情正常工作:

如何从 Python 脚本调用 C++:

  1. 安装 CYTHON:要安装将 python 脚本与 c/c++ 集成的工具 Cython,请访问:https ://pypi.python.org/pypi/Cython/

  2. 下载示例:从此处下载 C++ 实现示例:http ://wiki.cython.org/WrappingCPlusPlus?action=AttachFile&do=get&target=cythoncpp.tgz

  3. 准备 C++ 源文件:确保您的 *.cpp 和 *.h 文件是正确的。在下载的示例中,文件名为 cpp_rect.h 和 cpp_rect.cpp

  4. CREATE PYTHON WRAPER CPLASS:根据下载示例中的 rectangle.pyx 文件或http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html?highlight=cpp#create-cython-wrapper-中描述的模型班级

  5. 准备 SETUP.PY 文件:下载的示例已包含在此文件中,但可以在本教程中找到更多信息:http ://docs.cython.org/src/userguide/wrapping_CPlusPlus.html?highlight=cpp#specify-c -语言在设置-py。[PS: 1 最简单的编译方法是使用 disutilis 包,使用 setup.py 文件。有关编译选项的更多信息,请访问http://docs.cython.org/src/reference/compilation.html#

  6. 尝试编译:从源文件所在的同一文件夹转到终端。此时您已经拥有 4 个文件:cpp_rect.h、cpp_rect.cpp、rectangle.pyx 和 setup.py。从那里,执行命令$ python setup.py build_ext --inplace

  7. 如果您收到 g++ 错误,例如发生在我身上:“无法执行 gcc-4.2:没有这样的文件或目录”,您可以破解标志系统做sudo ln -s /usr/bin/gcc /usr/bin/gcc-4.2. 比重复上一步。

  8. 测试您的代码:此时,您拥有所需的一切:setup.py 与 rectangle.pyx 一起用于生成 rectangle.so 文件,这就是我们所需要的!只需构建一个 pythons 脚本来测试您的集成。幸运的是,该示例已经包含一个名为 use_rect.py 的测试脚本。

现在只需使用“ $ python userect.py”从终端运行它

于 2013-08-23T14:04:33.767 回答
1

这是使用 SWIG 的示例:

调用 C++ 函数“流入”的 Python 代码:

 import inflow    # importing C++ inflow library
 nframes = 25
 print 'calling inflow function in loop ...'
 for i in xrange(0,1001):
      z = inflow.inflow(""" arguments""")
     """ code does something with z """

C++ 函数将像往常一样:

 #include <iostream>
 #include <vector>
  inflow(/* arguments from Python*/)
  {
   /* code does something */

  }

现在要与 Python 交互,步骤如下:

1) 重要 - 确保您在此步骤中尝试绑定的 C++ 代码的名称与命令中给出的名称不同。否则它将被 swig 代码覆盖。

假设 example_wrap.cpp 是您要与 Python 交互的文件,“example.i”是 SWIG 接口文件。SWIG 将生成一个名为 example.cpp 的新文件。

2) swig -c++ -python -o example_wrap.cpp example.i

3) g++ -I /usr/include/python2.7 -fPIC -c example_wrap.cpp -o example_wrap.o

4) g++ -shared -o _example.so example_wrap.o

想法是编译后的模块名称应以下划线开头,后跟名称。

5)在术语中打开Python,然后说

from example import *

然后开始调用函数。

6) 来源:http ://www.iram.fr/~roche/code/python/SWIG.html# purpose

该示例的接口文件如下所示:

 %module example
 %{
   #include "example.h"
 %}

 %include "std_vector.i"
 // Instantiate templates used by example
 namespace std {
  %template(IntVector) vector<int>;
  %template(DoubleVector) vector<double>;
  }

  // Include the header file with above prototypes
  %include "example.h"
于 2013-08-20T19:10:22.443 回答
1
  1. 我认为你应该看看boost python,它是一个了不起的库,也适用于 linux、windows 和 mac。使用 boost python,您可以导出您的类和函数,以便直接从 python 访问它们。例子很多,文档很好!!!

  2. 使用 boost python,您应该定义要公开的函数/类,然后它们将您的源代码编译成一个库文件,该库文件将在 python 中导入。

于 2013-08-26T18:45:04.817 回答
0

简单、有效、快速的方法:

无效方法

测试.cpp

#include <iostream>
extern "C" void Print()
{
    std::cout << "This is data from inside a c++ file." << std::endl;
}

编译时命令

g++ -c -fPIC test.cpp -o test.o // DO NOT FORGET '-fPIC'
g++ -shared -o test.so test.o // FOR UNIX ONLY

主文件

from ctypes import cdll

test = cdll.LoadLibrary('./test.so')
test.Print()

传递和返回值

在 test.cpp

extern "C" int Multiply(int a, int b)
{
    return a*b;
}

在 Main.py 从 ctypes 导入 cdll

test = cdll.LoadLibrary('./test.so')
value = test.Multiply(5,5)
print(value)


总结
不需要额外的库。
不需要构造函数。
不需要 c++ 类。
不需要公开声明。

只需创建一个方法并将其标记为extern "C"
然后在 python 中调用它。

于 2022-01-24T09:53:30.003 回答