栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python ctypes返回函数指针数组

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python ctypes返回函数指针数组

事情并不像人们想象的在1个那样容易ST一目了然。我将发布一个虚拟示例,该示例恰好包含使用 .dll s( .so
s)中的函数的2种方式(如[Python 3.Docs]中所述:ctypes-
Python的外部函数库)。

dll00.c

#include <stdio.h>#if defined(_WIN32)#  define DLL00_EXPORT __declspec(dllexport)#  pragma warning(disable: 4477)  // !!! Just to avoid having additional pre (macro for size_t), do NOT do this !!!#else#  define DLL00_EXPORT#endif#define PRINT_MSG_0() printf("        [%s] (%d) - [%s]n", __FILE__, __LINE__, __FUNCTION__)#define PRINT_MSG_1I(ARG0) printf("        [%s] (%d) - [%s]:  ARG0: %dn", __FILE__, __LINE__, __FUNCTION__, ARG0)static int IsValidInt(int i) {    PRINT_MSG_1I(i);    return -i;}static int InvalidInt() {    PRINT_MSG_0();    return 0;}static int IsValidSize (size_t i) {    PRINT_MSG_1I(i);    return -i;}typedef struct DllInterfaceV2Struct {    int (__cdecl *IsValidIntFuncPtr)(int i);    int (__cdecl *InvalidIntFuncPtr)();    int (__cdecl *IsValidSizeFuncPtr)(size_t i);} DllInterfaceV2;static DllInterfaceV2 intfV2 = { IsValidInt, InvalidInt, IsValidSize };#if defined(__cplusplus)extern "C" {#endifDLL00_EXPORT const DllInterfaceV2 *GetInterfaceV2(int version);#if defined(__cplusplus)}#endifDLL_EXPORT const DllInterfaceV2 *GetInterfaceV2(int version) {    if (version == 2) {        return &intfV2;    } else {        return NULL;    }}

pre00.py

#!/usr/bin/env python3import sysimport ctypesDLL_NAME = "test00.dll"DLL_FUNC_NAME = "GetInterfaceV2"# "Define" the Python counterparts for C stuff in order to be able to use itIsValidIntFuncPtr = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)InvalidIntFuncPtr = ctypes.CFUNCTYPE(ctypes.c_int)IsValidSizeFuncPtr = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_size_t)class DllInterfaceV2(ctypes.Structure):    _fields_ = [        ("is_valid_int", IsValidIntFuncPtr),        ("invalid_int", InvalidIntFuncPtr),        ("is_valid_size", IsValidSizeFuncPtr)    ]# Now, play with C stuffdef test_interface_ptr(intf_ptr):    print("Testing returned interface: {:}n".format(intf_ptr))    if not intf_ptr:        print("    NULL pointer returned from Cn")        return    intf = intf_ptr.contents  # Dereference the pointer    res = intf.is_valid_int(-2718281)    print("    `is_valid_int` member returned: {:d}n".format(res))    res = intf.invalid_int()    print("    `invalid_int` member returned: {:d}n".format(res))    res = intf.is_valid_size(3141592)    print("    `is_valid_size` member returned: {:d}nn".format(res))def main():    test_dll = ctypes.CDLL(DLL_NAME)    get_interface_v2_func = getattr(test_dll, DLL_FUNC_NAME)  # Or simpler: test_dll.GetInterfaceV2    get_interface_v2_func.argtypes = [ctypes.c_int]    get_interface_v2_func.restype = ctypes.POINTER(DllInterfaceV2)    pintf0 = get_interface_v2_func(0)    test_interface_ptr(pintf0)    pintf2 = get_interface_v2_func(2)    test_interface_ptr(pintf2)if __name__ == "__main__":    print("Python {:s} on {:s}n".format(sys.version, sys.platform))    main()

注意事项

  • C 部分:

    • 我必须添加一些虚拟代码以测试和说明行为
    • 尽管您提到它不可修改,但我还是做了一些更改(主要是命名/编码风格,…):
    • 两个字母大小写和 下划线 都不太好(至少对我来说)
    • (函数,类或任何其他)名称中的“ my ”(或其任何变体)简直是伤脑筋
    • Python 部分:

    • 正如我在评论中所述,必须在 Python中 “复制” C 内容 __

    • 尽管我认为这是一个 主要的 设计缺陷,但为了使问题尽可能接近问题,我只是遵循了它( GetInterfaceV2 V2 部分)考虑到其arg( 版本 )没有任何意义)

    • 我个人的观点(尽管没有所有上下文)是(为了确保可伸缩性),该函数应返回通用结构,并带有一个可由客户端应用程序检查的附加字段(例如 version )。

输出

(py35x64_test)

e:WorkDevStackOverflowq051507196>”c:Installx86MicrosoftVisual Studio
Community2015vcvcvarsall.bat” x64

(py35x64_test) e:WorkDevStackOverflowq051507196>dir /bpre00.pydll00.c(py35x64_test) e:WorkDevStackOverflowq051507196>cl /nologo dll00.c

/link /DLL /OUT:test00.dll
dll00.c
Creating library test00.lib and object test00.exp

(py35x64_test) e:WorkDevStackOverflowq051507196>dir /bpre00.pydll00.cdll00.objtest00.dlltest00.exptest00.lib(py35x64_test)

e:WorkDevStackOverflowq051507196>”e:WorkDevVEnvspy35x64_testscriptspython.exe”
pre00.py
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit
(AMD64)] on win32

Testing returned interface: <__main__.LP_DllInterfaceV2 object at

0x00000219984EBAC8>

   NULL pointer returned from CTesting returned interface: <__main__.LP_DllInterfaceV2 object at

0x00000219984EBB48>

        [dll00.c] (16) - [IsValidInt]:  ARG0: -2718281    `is_valid_int` member returned: 2718281        [dll00.c] (22) - [InvalidInt]    `invalid_int` member returned: 0        [dll00.c] (28) - [IsValidSize]:  ARG0: 3141592    `is_valid_size` member returned: -3141592


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/470560.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号