我剛開始使用Linux上的gcc。我遵循教程here,除了我正在使用g ++編譯器。使用ctypes.cdll.LoadLibrary從Python加載庫時無效的ELF標頭
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 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;
}
改性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()
嘗試在終端....
[email protected]:~/development/libtest$ ./build_script.sh
[email protected]:~/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;
}
謝謝。靜態vs共享是我需要開始的。查看我的更新,瞭解我如何爲這個小例子工作。我一定會接受你的建議(關於cython),以便我將來編寫任何代碼。 – oob