C++ で 2 つのモジュールを作成し、Cython 経由で Python にインポートしました。最初のモジュールは Generator と呼ばれ、2 つのクラスが含まれています。疑似乱数を生成するアルゴリズムを実装する MersenneTwister と、MersenneTwister オブジェクトを作成するシングルトンである Generator クラスです。2 番目のモジュールは KMeans と呼ばれ、データをクラスタリングするための K-Means アルゴリズムを実装する関数呼び出し KMeans が含まれています。両方のモジュールについて、対応する .pyx ファイルを作成しました。このファイルは cython で正常にコンパイルされ、g++ を使用して .so ファイルを作成し、Python で KMeans.so ファイルをインポートしました。 : 未定義のシンボル: _ZN9Generator8instanceEv
g++ -shared -pthread -fPIC -fwrapv -fno-strict-aliasing -o file.so file.cpp を使用して .cpp ファイルをコンパイルしました。
# KMeans.pyx files
include "Generator.pyx"
from libcpp.vector cimport vector
cdef import from "KMeans.h" :
cdef struct Pair:
vector[vector[double]] C
vector[unsigned int] J
Pair(vector[vector[double]] _C, vector[unsigned int] _J)
cdef double s(vector[double] X, vector[double] c)
cdef void AddToCodeword(vector[double] X, vector[double] c)
cdef Pair KMeans(unsigned int k, vector[vector[double]] X) except +
def KMean(unsigned k, X):
cdef Pair returnValue = KMeans(k, X)
return returnValue.C, returnValue.J
#Generator.pyx file
cdef extern from "mt.h":
cppclass MersenneTwister:
MersenneTwister()
#public members
double random()
void init_genrand(unsigned long s)
void init_by_array(unsigned long* init_key, int key_length)
unsigned long genrand_int32()
long genrand_int31()
double genrand_real1()
double genrand_real2()
double genrand_real3()
double genrand_res53()
#private members
unsigned long* mt_
int mti_
unsigned long* init_key_
int key_length_
unsigned long s_
int seeded_by_array_
int seeded_by_int_
#static members
cdef extern from "mt.h" namespace "MersenneTwister":
int N = 624
int M = 397
unsigned long MATRIX_A = 0x9908b0dfUL
unsigned long UPPER_MASK = 0x80000000UL
unsigned long LOWER_MASK = 0x7fffffffUL
cdef extern from "generator.h" namespace "Generator":
MersenneTwister *_ptr_
MersenneTwister *instance()
MersenneTwister *instance(unsigned int seed)