0

dll から関数を呼び出したい Python ファイルがあります。

関数のプロトタイプは次のとおりです。

typedef double real_T;
extern real_T __declspec(dllexport) RectIntersect(const real_T rect1[8], const real_T rect2[8]);

Python コード:

import math;
import ctypes;
from ctypes import *
import numpy;


# this module shall always be executed directly
if __name__ == '__main__':
    print "Program started !";
    rect = ctypes.c_double * 8;
    rect1 = rect(1.1, 2.45, 3, 4, 5, 6, 7, 8);
    rect2 = rect(1.6, 3.45, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1);

    # Load DLL into memory.

    hllDll = ctypes.WinDLL ("IntersectDLL.dll");
    hllDll.RectIntersect.argtypes =[ctypes.c_double * 8, ctypes.c_double * 8];
    hllDll.RectIntersect (rect1, rect2);

エラーが発生します:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.0\visualstudio_py_util.py", line 70, in exec_file
    exec(code_obj, global_variables)
  File "D:\Sandboxes\SRR2T0\06_Algorithm\05_Testing\05_Test_Environment\algo\smr200_bbt\valf_tests\adma\test.py", line 18, in <module>
    hllDll.RectIntersect (rect1, rect2);
ValueError: Procedure probably called with too many arguments (8 bytes in excess)

助けてください :(。 ....

4

1 に答える 1

1

C 宣言

real_T RectIntersect(const real_T rect1[8], ...)

は次のものと完全に同等です (そして C コンパイラによって置き換えられます):

real_T RectIntersect(const real_T *rect1, ...)

これは、DLL 内の関数が実際には 8 つの double の配列を想定しているのではなく、double へのポインターを想定していることを意味します。このポインターには、8 つの double の配列を作成するためにさらに 7 つが続く可能性があります (ただし、この部分はチェックされません)。これは、ctypes でそれを書くには他の方法が必要であることを意味します。例えば:

hllDll.RectIntersect.argtypes =[ctypes.POINTER(ctypes.c_double * 8),...]

で渡しctypes.byref(rect1)ます。

別の方法: ctypes の代わりに CFFI ( http://cffi.readthedocs.org/ ) を使用すると、この問題は発生しない可能性があります。これは、C の型により近いものです。

import cffi
ffi = cffi.FFI()
ffi.cdef("""
    typedef double real_T;
    real_T RectIntersect(const real_T rect1[8], const real_T rect2[8]);
""")
lib = ffi.dlopen("IntersectDLL.dll")
rect1 = ffi.new("real_T[8]", [1.1, 2.45, 3, 4, 5, 6, 7, 8])
rect2 = ffi.new("real_T[8]", [1.6, 3.45, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1])
lib.RectIntersect(rect1, rect2)
于 2013-08-23T13:23:32.953 に答える