0

単純な C ファイルを使用して python を拡張しようとしています。独自の Python モジュールの作成には成功しましたが、コンパイルしてスタンドアロンの実行可能ファイルとして実行するには、C ファイル自体も必要です。正常にコンパイルできますが、実行しようとすると、「バイナリ ファイルを実行できません: Exec フォーマット エラー」というエラーが表示されます。

これが私の C ソース ファイル (hellomodule.c) です。

#include <Python.h>

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

//Only used by Python
static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    //printf("Hello %s!\n", name);
    print_hello("World");

    Py_RETURN_NONE;
}

//Only used by Python
static PyMethodDef HelloMethods[] =
{
    {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
    {NULL, NULL, 0, NULL}
};

//Only used by Python
PyMODINIT_FUNC
inithello(void)
{
    (void) Py_InitModule("hello", HelloMethods);
}

int main(){
    print_hello("World");
}

次のようにして、エラーや警告なしで「正常に」コンパイルできます。

gcc -I /usr/include/python2.7 -c hellomodule.c -o hellomodule

「hellomodule」ファイルを実行可能にした後、それを実行するとエラーが発生します。

-bash: ./hellomodule: cannot execute binary file: Exec format error

なぜこのようなエラーが発生するのでしょうか?

4

1 に答える 1

1

実行可能ファイルではないオブジェクト ファイルを実行しようとしています。コードをモジュールとしてコンパイルするには、次のようなものが必要です

gcc -Wall -Werror -Wextra -O2 -I/usr/include/python2.7 \
    -shared hellomodule.c -o hellomodule.so -lpython2.7

しかし、すべてに正しくリンクし、可能なすべてのインクルードディレクトリを追加するには、次のpython-configように呼び出す必要があるというスクリプトがあります

gcc -Wall -Werror -Wextra -O2 `python-config --includes` \
    -shared hellomodule.c -o hellomodule.so `python-config --libs`

さらに良いことに、スクリプトはCFLAGSandLDFLAGSも提供します。

gcc -Wall -Werror -Wextra -O2 `python-config --cflags` \
    -shared hellomodule.c -o hellomodule.so `python-config --ldflags`

次に、結果のファイルを にコピーします/usr/lib/python2.7/site-packages

その後、このようなPythonスクリプトでモジュールをロードできます

import hellomodule

オブジェクト ファイルは、最終的なバイナリを生成するためにリンカー (ldおそらく)によって最終的に使用される中間バイナリ ファイルです。Pythonモジュールにはmain()機能がなく、PythonインタープリターがモジュールをPythonスクリプト/プログラムにロードするために使用するいくつかの定義済みシンボルをエクスポートする、実行時にロード可能な共有オブジェクトでなければなりません。

注: これを正しく行い、死なないようにするには、次のように Makefile を作成します。

CFLAGS = `python-config --cflags` -Wall -Werror # add more if needed
LDFLAGS = `python-config --ldflags` # add more if needed
OBJS = hellomodule.o # add more if needed

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -shared -o modulename.so $(OBJS)

%.o: %.c
    $(CC) -c $(CFLAGS) $<

インデントにスペースではなくタブを使用していることを確認してから、 Makefileとソース ファイルとmake同じディレクトリで実行してください。

于 2016-01-07T22:49:15.340 に答える