使用ctypes.cdll.LoadLibrary从Python加载库时,ELF头无效
Invalid ELF header when loading library from Python using ctypes.cdll.LoadLibrary
我刚刚开始在Linux上使用gcc。我在这里遵循教程,除了我使用的是g++编译器。
hello_fn.cpp
#include <stdio.h>
#include "hello.h"
void
hello (const char * name)
{
printf ("Hello, %s!n", name);
}
bye_fn.cpp
#include <stdio.h>
#include "hello.h"
void
bye (void)
{
printf ("Goodbye!n");
}
hello.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所说的,我可能不会在新代码上走这个方向,但我能够让它与一个大型的遗留c++库一起工作,我正在将其从Windows移植到Linux。我们需要一个前端来从这个库中调用一些长时间运行的函数,所以我认为Python可能是最简单的。这些函数创建了大量输出,并且只返回一个整数返回代码,所以也许我可以避免Cat Plus Plus所说的"痛苦"的东西。
这就是我所做的。
修改hello_fn.cpp
#include <stdio.h>
#include "hello.h"
extern "C" int
hello (void)
{
return 16;
}
修改by_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);
buildscript.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
test.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,但我从来没用过,所以不能告诉你它在实践中有多好。
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 无法访问嵌套类.类的使用无效
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 错误:从"int"到枚举c++的转换无效
- 如何修复此错误:className::className的无效使用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- C++-模板嵌套类的引用初始化无效
- 错误:无效的预处理指令 #i 的意思是 #if?
- 多维数组 C++ 中数组下标的类型"int[int]"无效
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 从 'int' 到 'int*' CPP 的转换无效
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- C++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- 声明为无效的变量或字段'...' Ardunio 编译器上的错误
- 数组下标的类型"float*[float]"无效
- 使用ctypes.cdll.LoadLibrary从Python加载库时,ELF头无效