Python調用C++接口,並支持callback

1. C++代碼

 

#include <stdio.h>
extern "C"{
int Print(const char *msg)
{
printf("%s\n", msg);
return 0;
}

int Add(int a, int b)
{
return a + b;
}

    struct Vector
    {
        int x;
        int y;
        int z;
    };

    struct Vector AddVector(struct Vector a, struct Vector b)
    {
        Vector v;
        v.x = a.x + b.x;
        v.y = a.y + b.y;
        v.z = a.z + b.z;
        return v;
    }

/*    typedef struct Vector (*pfnAddVectorCallback)(struct Vector a, struct Vector b);

    struct Vector AddVectorCallback(pfnAddVectorCallback callback, struct Vector a, struct Vector b)
    {
        return callback(a, b);
    }
*/
typedef void (*pfnAddVectorCallback)(struct Vector a, struct Vector b, struct Vector *c);

    struct Vector AddVectorCallback(pfnAddVectorCallback callback, struct Vector a, struct Vector b)
    {

        printf("AddVector begin a.x=%d,a.y=%d,a.z=%d\n", a.x,a.y, a.z);
        printf("AddVector begin b.x=%d,b.y=%d,b.z=%d\n", b.x,b.y, b.z);
        Vector vc;
        vc.x = 0;
        vc.y = 0;
        vc.z = 0;
        printf("before callback c.x=%d,c.y=%d,c.z=%d\n", vc.x, vc.y, vc.z);
        callback(a, b, &vc);
        printf("after callback c.x=%d,c.y=%d,c.z=%d\n", vc.x, vc.y, vc.z);
        return vc;
    }
}

2. 編譯

g++ -fPIC mydll.cpp -o mydll.so -shared

3. Python代碼

from ctypes import *
import ctypes

mydll = ctypes.CDLL('/home/zhouqq/work/test/mydll.so')
mydll.Print('this if from python')

class VECTOR(Structure):
     _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)]


print VECTOR.x, VECTOR.y, VECTOR.z
vector_a = VECTOR(1, 2, 3)
vector_b = VECTOR(2, 3, 4)
mydll.AddVector.restype = VECTOR
vector_c = mydll.AddVector(vector_a, vector_b)
print vector_c.x, vector_c.y, vector_c.z

mydll.AddVectorCallback.restype = VECTOR
ADDVECTORCALLBACK = CFUNCTYPE(None, VECTOR, VECTOR, POINTER(VECTOR))
#def AddVectorImpl(a, b, c):
#    c.contents = VECTOR(a.x + b.x, a.y + b.y, a.z + b.z)


def AddVectorImpl(a, b, c):
    c.contents.x = a.x * b.x
    c.contents.y = a.y * b.y
    c.contents.z = a.z * b.z

vector_d = VECTOR(0,0,0)
print vector_d.x, vector_d.y, vector_d.z

vector_d = mydll.AddVectorCallback(ADDVECTORCALLBACK(AddVectorImpl), VECTOR(1,2,3), VECTOR(2,3,4))
#print vector.x, vector.y, vector.z
print vector_d
print vector_d.x, vector_d.y, vector_d.z
print 'done'

 

4.  坑一


def AddVectorImpl(a, b, c):
    c.contents.x = a.x * b.x
    c.contents.y = a.y * b.y
    c.contents.z = a.z * b.z
    return c.contents
    #c.contexts.x = a.x + b.x
    #c.contexts.y = a.y + b.y
    #c.contexts.z = a.z + b.z

4.  坑二

mydll.AddVectorCallback.restype = VECTOR # MUST NEED
ADDVECTORCALLBACK = CFUNCTYPE(None, VECTOR, VECTOR, POINTER(VECTOR))

 

6. 參考資料(有bug):

https://blogs.msdn.microsoft.com/yizhang/2018/01/20/calling-c-functions-from-python-part-1-using-ctypes/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章