社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

使用Cype调用带有Python参数的C++方法导致“不知道如何转换参数”错误

Tom Spargo • 3 年前 • 1394 次点击  

我试图从Python 3使用下面的C++类。7,但无法让第一个方法“设置”工作,更不用说运算符重载方法了。我尝试了Python包装器和extern块的许多变体,但我要么遇到了“不知道如何转换参数5”错误,要么遇到了分段错误。网上的例子和我找到的答案都太基本了,或者是解决了其他问题。

我的argtypes第一个参数应该是指向对象的指针吗?我不知道用什么语法来表示。

CMatrix。h:

#include <stdio.h>

class CMatrix
{
public:
    CMatrix(int d1);
    CMatrix(int d1, int d2);
    CMatrix(int d1, int d2, int d3);
    CMatrix (float f1, float f2, float f3);
    ~CMatrix();
    
    void Set(int x, int y, int z, float f);
    void operator=(const float f);
    CMatrix& operator=(const CMatrix &cm);
    inline float& operator()(const int i) {
        return m[i];}
    inline float& operator()(const int i, const int j) {
        return m[i*s2+j];}
    inline float& operator()(const int i, const int j, const int k) {
        return m[i*s23+j*s3+k];}
    int s1, s2, s3;     // dimensions of array
    int s23;            // s2*s3;
    float *m;           // pointer to first element of matrix.
    int dimensions;     // 1, 2, or 3.
};

extern "C" {
    CMatrix* CMatrix_new1(int i) {return new CMatrix(i); }
    CMatrix* CMatrix_new2(int i, int j) {return new CMatrix(i, j); }
    CMatrix* CMatrix_new3(int i, int j, int k) {return new CMatrix(i, j, k); }
    void CMatrix_Set(CMatrix* cm, int x, int y, int z, float f) {cm->Set(x, y, z, f); }
}

cmWrapper。py:

import ctypes as c
lib = c.cdll.LoadLibrary('./libCMatrix.o')
lib.CMatrix_Set.argtypes = [c.c_int, c.c_int, c.c_int, c.c_float]

class CMatrix(object):
    def __init__(self, i, j, k):
        if j==0 and k==0:
            self.obj = lib.CMatrix_new1(i)
        elif k==0:
            self.obj = lib.CMatrix_new2(i, j)
        else:
            self.obj = lib.CMatrix_new3(i, j, k)

    def Set(self, x, y, z, f):
        lib.CMatrix_Set(self.obj, x, y, z, f)

cm = CMatrix(2, 3, 0)
cm.Set(1, 2, 0, 99.0)

追溯:

>>> import cmWrapper
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../ctypes/cmWrapper.py", line 18, in <module>
    cm.Set(1, 2, 0, 99.0)
  File "/.../ctypes/cmWrapper.py", line 15, in Set
    lib.CMatrix_Set(self.obj, x, y, z, f)
ctypes.ArgumentError: argument 5: <class 'TypeError'>: Don't know how to convert parameter 5

如果有问题,我用C++编译了C++代码:

g++ -c -fPIC CMatrix.cpp -o CMatrix.o
g++ -shared -Wl -o libCMatrix.o CMatrix.o

这是在运行10.15.7的Mac上。

来自lldb:

Executable module set to "/Library/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python".
Architecture set to: x86_64h-apple-macosx-.
(lldb) 
There is a running process, detach from it and attach?: [Y/n] n
(lldb) thread list
Process 57460 stopped
* thread #1: tid = 0x47364c, 0x00007fff202f5656 libsystem_kernel.dylib`__select + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
(lldb) thread continue
Resuming thread 0x47364c in process 57460
Process 57460 resuming
Process 57460 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x13835f20)
    frame #0: 0x00000001015f19b2 libCMatrix.o`CMatrix::Set(int, int, int, float) + 34
libCMatrix.o`CMatrix::Set:
->  0x1015f19b2 <+34>: movl   (%rax), %esi
    0x1015f19b4 <+36>: movl   0x4(%rax), %edx
    0x1015f19b7 <+39>: movl   0x8(%rax), %ecx
    0x1015f19ba <+42>: movl   0xc(%rax), %r8d
Target 0: (Python) stopped.
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/130722
 
1394 次点击  
文章 [ 2 ]  |  最新文章 3 年前