python类型如何转换为指针_如何将ctypes指针转换为Python类的实例

Say you have the following C code:

typedef void (*PythonCallbackFunc)(void* userData);

void cb(PythonCallbackFunc pcf, void* userData)

{

pcf(userData);

}

and the following Python 3 code:

import ctypes

class PythonClass():

def foo():

print("bar")

CALLBACK_TYPE = ctypes.CFUNCTYPE(None, ctypes.c_void_p)

def callback(userData):

instanceOfPythonClass = ???(userData) #

instanceOfPythonClass.foo()

lib = ctypes.cdll.LoadLibrary("path/to/lib.dll")

pc = PythonClass()

lib.cb(ctypes.byref(pc), CALLBACK_TYPE(callback))

Where "path/to/lib.dll" is a compiled binary of the C code up top.

How would one go about casting the userData parameter in "callback" back to an instance of PythonClass, so one could call the function "foo()"?

解决方案

Based on [Python 3.Docs]: ctypes - A foreign function library for Python, I did some changes to your code in order to make it work.

dll.c:

#include

#if defined(_WIN32)

# define DLL_EXPORT __declspec(dllexport)

#else

# define DLL_EXPORT

#endif

#define C_TAG "From C"

#define PRINT_MSG_0() printf("%s - [%s] (%d) - [%s]\n", C_TAG, __FILE__, __LINE__, __FUNCTION__)

typedef void (*PythonCallbackFuncPtr)(void *userData);

DLL_EXPORT void callPython(PythonCallbackFuncPtr callbackFunc, void *userData)

{

PRINT_MSG_0();

callbackFunc(userData);

}

code.py:

import sys

from ctypes import CDLL, CFUNCTYPE, \

py_object

CallbackFuncType = CFUNCTYPE(None, py_object)

dll_dll = CDLL("./dll.dll")

call_python_func = dll_dll.callPython

call_python_func.argtypes = [CallbackFuncType, py_object]

class PythonClass():

def foo(self):

print("Dummy Python method")

def callback(userData):

print("From Python: {:s}".format(callback.__name__))

userData.foo()

def main():

instance = PythonClass()

call_python_func(CallbackFuncType(callback), instance)

if __name__ == "__main__":

print("Python {:s} on {:s}\n".format(sys.version, sys.platform))

main()

Notes:

When dealing with Python types, use ctypes.py_object (which is a wrapper over PyObject) rather than ctypes.c_void_p

Always define argtypes (and restype) for C functions that you call from Python (e.g. call_python_func (which wraps callPython))

PythonClass.foo() was missing the 1st (self) argument and thus being just a function defined inside PythonClass instead of a method

Did other non critical changes (mostly renames)

Output:

(py35x64_test) e:\Work\Dev\StackOverflow\q052053434>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64

(py35x64_test) e:\Work\Dev\StackOverflow\q052053434>dir /b

code.py

dll.c

(py35x64_test) e:\Work\Dev\StackOverflow\q052053434>cl /nologo /DDLL dll.c /link /DLL /OUT:dll.dll

dll.c

Creating library dll.lib and object dll.exp

(py35x64_test) e:\Work\Dev\StackOverflow\q052053434>dir /b

code.py

dll.c

dll.dll

dll.exp

dll.lib

dll.obj

(py35x64_test) e:\Work\Dev\StackOverflow\q052053434>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py

Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32

From C - [dll.c] (18) - [callPython]

From Python: callback

Dummy Python method

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值