python c/c++書き込みdllを呼び出す

3839 ワード

この文章を翻訳したことに相当して、How to write a DLL/SO in C/C++ for Python、私の目的は私が失敗した状況を注釈することです.
まず、著者はCythonがより良いCのpythonパッケージとして使用できることをお勧めします.私は使っていません.直接vsのツールで次のdllを生成しましょう.
1、ソースコードの作成
C  

//test.c

__declspec(dllexport) int sum(int a, int b) {

    return a + b;

}

C++

//test.cpp

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int sum(int a, int b) {

    return a + b;

}

Windowsユーザー
__declspec(dllexport)は必須であり、プログラムを不要にすることもできる.defファイルにアクセスできますが、実は意味が分かりません.Linuxユーザーはこの接頭辞を無視することができます.
C++の接頭辞はCよりもextern「C」をカットし、コンパイラに余分なものを追加しないようにするため、C++のdllを作るなら、必要ですが、実は接頭辞を写せばいいのです.
ほとんどの例は直接書いてあります
extern "C"__declspec(dllexport)int sum(int a,int b)のようなものは、可読性の問題にすぎない.
また、C#のようなヘッダファイルを追加することもできます.
//test.h

int sum(int, int);

2,DLL/SOにコンパイル
dllの直接生成を教える以上、もちろんクラスライブラリプロジェクトを構築するのではなく、vsが提供するコマンドラインツールを直接使ってtestに移動しましょう.c/test.cppディレクトリを実行します.
>cl/LD test.c [...]/out:test.dll/dll/implib:test.lib test.obj    Creating library test.lib and object test.exp Note: cl use the file extension (.c or .cpp) to know if the source is written in C or C++.
Linuxユーザはgcc/g++で1つ生成する.soファイル:
gcc -Wall -Wextra -O -ansi -pedantic -shared test.c -o test.so
Note: the -shared option is responsible to create the .so.
Note: You can also use Dependency Walker or similar programs to see the list of the exported functions and check if the sum function is there.
以上未テスト
3,ctypesモジュールでdll/soにアクセス
python 2から5からctypesがデフォルトで含まれています.そうしない場合は、自分でインストールしてください(easyinstallまたはpip、またはダウンロード)
>>> from ctypes import cdll >>> mydll = cdll.LoadLibrary('test.dll') >>> mydll windowsは現在のディレクトリで自動的に検索し、Linuxはパスを入力してください:>>>from ctypes import cdll>>mydll=cdll.LoadLibrary('/home/wolf/test.so') >>> mydll テスト:>>mydll.sum <_FuncPtr object at 0x00AF6918>>>> mydll.sum(5, 3) >>> 8
==はい、以上は原文で、私の问题は以下の通りです:1、开発环境がx 64なので、64ビット版のpythonをインストールして、结果はいつも失败して、32ビット版をインストールして、以上のテストは直接合格して、绝対に64ビットの原因で、たとえこのdllは私の64ビットの机械の上でコンパイルしたのですとしても.x 64が組み込まれたpythonは何台も正常に調整されていません2、次はint配列と文字配列を入力する必要があるC方法です.
int CCaptionApp(int times,int length, int *ids,char *message)

{

    int n,m=0;

    for(n=0;n<length;n++)

    {

        m+=ids[n];

    }

    return m;

}

実測によると、文字配列はstringを直接伝えることができ、int配列も法のように砲撃したいと思っています.
>>from ctypes import cdll>>mydll=CDLL('test.dll')#ついでに別のロード方法をプレゼンテーションして、書くのが速い>>mydll.CCaptionApp(1,3,[3,4,5],'hello')
出力:
Traceback (most recent call last):   File "", line 1, in ctypes.ArgumentError: argument 3: :Don't know how to convert parameter 3この偶然は取れないようです(BTW,.netは直接インターネット[]で調整すればいいです)、
文書を調べた、そのうち15.17.1.13 Arrayのセクション:
>>> from ctypes import * >>> TenIntegers = c_int * 10 >>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) >>> print ii >>> for i in ii: print i, ... 1 2 3 4 5 6 7 8 9 10 >>>
長さで配列を構築し、OK、テストします.
>>> from ctypes import * >>> mydll = CDLL('test.dll') >>> mydll.CCaptionApp(1,3,(c_Int*3)(3,4,5),'hello') >>> 12
成功