gpt4 book ai didi

c++ - 使用 ctypes.cdll.LoadLibrary 从 Python 加载库时 ELF header 无效

转载 作者:行者123 更新时间:2023-11-30 01:27:52 30 4
gpt4 key购买 nike

我刚刚开始在 Linux 上使用 gcc。我正在学习教程 here , 除了我使用的是 g++ 编译器。

你好_fn.cpp

#include <stdio.h>
#include "hello.h"

void
hello (const char * name)
{
printf ("Hello, %s!\n", name);
}

再见_fn.cpp

#include <stdio.h>
#include "hello.h"

void
bye (void)
{
printf ("Goodbye!\n");
}

你好.h

void hello (const char * name);
void bye (void);

然后我在 shell 中运行以下命令:

$ g++ -Wall -c hello_fn.cpp
$ g++ -Wall -c bye_fn.cpp
$ ar cr libhello.a hello_fn.o bye_fn.o

然后我从 python 中尝试以下操作:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> test = ctypes.cdll.LoadLibrary(r'/home/oob/development/libtest/libhello.a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/ctypes/__init__.py", line 431, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python2.7/ctypes/__init__.py", line 353, in __init__
self._handle = _dlopen(self._name, mode)
OSError: /home/jeff/development/libtest/libhello.a: invalid ELF header

我的想法是用 C++ 编写一些函数并从 Python 调用它们。有什么想法吗?

更新:我能够让事情“正常工作”。根据 Cat Plus Plus 所说,对于新代码我可能不会朝这个方向发展,但我能够让它与我从 Windows 移植到 Linux 的大型遗留 c++ 库一起工作。我们需要一个前端来从这个库中调用一些长时间运行的函数,所以我认为 Python 可能是最简单的。这些函数创建了大量输出并且只返回一个整数返回码,所以也许我可以避免 Cat Plus Plus 所说的“痛苦”的东西。

这是我做的。

修改后的 hello_fn.cpp

#include <stdio.h>
#include "hello.h"

extern "C" int
hello (void)
{
return 16;
}

由_fn.cpp 修改

#include <stdio.h>
#include "hello.h"

extern "C" void
bye (void)
{
printf ("Goodbye!\n");
}

修改后的hello.h

extern "C" int hello (void);
extern "C" void bye (void);

构建脚本.sh

#!/bin/bash

rm *.o
rm *.so

g++ -fpic -g -c -Wall hello_fn.cpp
g++ -fpic -g -c -Wall bye_fn.cpp
#make a shared library, not a static library (thanks cat plus plus)
g++ -shared -o libhello.so hello_fn.o bye_fn.o

测试.py

#!/usr/bin/python

import ctypes

c = ctypes.cdll.LoadLibrary(r'/home/jeff/development/libtest/libhello.so')
a = c.hello()
print 'hello was ' + str(a)
c.bye()

在终端中尝试....

oob@ubuntu:~/development/libtest$ ./build_script.sh 
oob@ubuntu:~/development/libtest$ python test.py
hello was 16
Goodbye!

我们的遗留库并没有真正使用任何特定于 Windows 的 C++ 东西(感谢编写该代码的人),因此它是一个非常简单的端口。我们有几个函数使用 extern "C"来公开函数。对于端口,我做了以下更改:

#ifdef LINUX
#define __stdcall
#endif
#ifdef WINDOWS
#define __stdcall __stdcall
#endif

对于我们的一个功能,我可以保持不变,例如:

extern "C" long __stdcall reform_proj {
//do a bunch of stuff
return 0;
}

最佳答案

ctypes 用于加载共享库。 ar 创建目标文件的存档,也称为静态 库。您不能使用 ctypes 加载该文件,它只能被链接器理解。

另一个问题是,通过 ctypes 使用 C++ 共享库即使不是完全不可能也很痛苦。只是不要。使用 Cython相反,编写一个适当的 Python 扩展来与你的 C++ 代码交互(然后你可以静态或动态地链接它,它就会工作)。

另一个选项是 Boost.Python ,但它的文档较少,但它的好处是直接在 C++ 代码中定义 Python 模块,而不是使用以另一种语言编写的包装器。

第三个是SWIG ,但我从未使用过它,所以无法告诉您它在实践中的效果如何。

关于c++ - 使用 ctypes.cdll.LoadLibrary 从 Python 加载库时 ELF header 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8263914/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com