次のようにしますが、エラーが発生します。pythonのpass構造体と入出力関数のポインタへのポインタ
ctypesの使用に間違いがありますか、渡すパラメータのタイプに問題がありますか?
はPythonでC関数に渡された右のパラメータを生成します。
は、私は約考えるべき三点があるかもしれないと思います。
struct to structの型のポインタを渡します。
structが必要な場合は、指定された配列に依存します(pythonコードで構造体が必要です)。
私はc、特にポインタの新機能です。
Cコード:構造体、ansfer.h
typedef unsigned char boolean_T;
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
Pythonが呼び出された関数、ansfer.c
void ansferA(const emxArray_real_T *dataArray, double H, emxArray_real_T *TE,
emxArray_real_T *Lag)
{
...
P2 += dataArray->data[a + dataArray->size[0] * b];
...
TE->data[a + TE->size[0] * b] = te;
Lag->data[a + Lag->size[0] * b] = h;
...
}
次いで、gcc -o libansfer.so -shared -fPIC *.c
libansfer.soが生成されます。
私は、アドバイスに従ってtest.pyを書き換えます。次のように構造体を追加します。
のpythonコード:test.py
import numpy as np
import ctypes
c_double_p = ctypes.POINTER(ctypes.c_double)
c_int_p = ctypes.POINTER(ctypes.c_int)
class emxArray_real_T(ctypes.Structure):
_fields_ = [
("data", c_double_p),
("size", c_int_p),
("allocatedSize", ctypes.c_int),
("numDimensions", ctypes.c_int),
("canFreeData", ctypes.c_bool)
]
indata = np.array([[1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1],[2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2,2.2],[3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,3.3,2.2,2.2,2.2]])
LL, CC = indata.shape
TE = np.zeros((LL,LL), dtype=np.double)
Lag = np.zeros((LL,LL), dtype=np.double)
SS = np.array([LL, CC])
instruct = emxArray_real_T()
instruct.data = c_double_p(ctypes.c_double(indata.ctypes.data))
instruct.size = c_int_p(ctypes.c_int(SS.ctypes.data))
instruct.allocatedSize = ctypes.c_int(LL*CC)
instruct.numDimensions = ctypes.c_int(2)
instruct.canFreeData = ctypes.c_bool(0)
ss = np.array([LL, LL])
outstruct1 = emxArray_real_T()
outstruct1.data = c_double_p(ctypes.c_double(TE.ctypes.data))
outstruct1.size = c_int_p(ctypes.c_int(ss.ctypes.data))
outstruct1.allocatedSize = ctypes.c_int(LL*LL)
outstruct1.numDimensions = ctypes.c_int(2)
outstruct1.canFreeData = ctypes.c_bool(0)
outstruct2 = emxArray_real_T()
outstruct2.data = c_double_p(ctypes.c_double(Lag.ctypes.data))
outstruct2.size = c_int_p(ctypes.c_int(ss.ctypes.data))
outstruct2.allocatedSize = ctypes.c_int(LL*LL)
outstruct2.numDimensions = ctypes.c_int(2)
outstruct2.canFreeData = ctypes.c_bool(0)
lib = ctypes.cdll.LoadLibrary('./libansfer.so')
lib.ansferA(instruct,ctypes.c_double(3), outstruct1, outstruct2)
が、同様のエラー
Traceback (most recent call last):
File "C:\Python27\testfile\test.py", line 106, in <module>
lib.ansferA(instruct,ctypes.c_double(3), outstruct1, outstruct2)
WindowsError: exception: access violation writing 0x0000000000000000
表示されているコードは、判読不能かつ不完全です。あなたの質問を正しく書いて、[mcve]を提供するために、時間をかけて読んでください。 – kaylum
Cは 'struct emxArray_real_T'のポインタを右端の2つの引数として要求していますが、ポインタをdoubleに渡しています。構造体をctypesに記述する必要があります。ポインタであるメンバの1つにアクセスしようとするとクラッシュする可能性があります。 – cdarke
'byref(ctypes.c_double(indata.ctypes。データ)) ''データ '("配列のメモリ領域へのポインタをPythonの整数として ")をとり、それを' double'(_not_aダブルポインタ!)にキャストし、そのダブルへのポインタをとります。 'indata.ctypes.data_as(ctypes.POINTER(ctypes.c_double))'は代わりに代わりに働きますが、cdarkeがstructについて書いたものを見てください。 – DavidW