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

Python ctypes cdll.LoadLibrary,实例化对象,执行其方法,私有变量地址被截断

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

Python ctypes cdll.LoadLibrary,实例化对象,执行其方法,私有变量地址被截断

始终(正确) 为 C中 定义的函数指定 argtypesrestype __,否则( C89 风格)它们将 默认为
int
(通常为 32bit ),生成 _ ! 未定义的行为!!!。在 _64位上 ,地址(大于 _ 2 GiB_
)将被截断(这正是您所遇到的)。检查[SO]:从Python通过ctypes调用的C函数返回错误值(@CristiFati的答案)以获取更多详细信息。

另外,遇到问题时,请不要忘记[Python 3.Docs]:ctypes-
Python的外部函数库

下面是代码的改编版本。

detector.cpp

#include <stdio.h>#include <memory.h>#include <fstream>#define C_TAG "From C"#define PRINT_MSG_2SP(ARG0, ARG1) printf("%s - [%s] (%d) - [%s]:  %s: 0x%0pn", C_TAG, __FILE__, __LINE__, __FUNCTION__, ARG0, ARG1)using std::endl;std::ofstream outFile;class Detector {    public:        Detector();        void process(int *pIn, int *pOut, int n);    private:        int m_var;};Detector::Detector() : m_var(0) {    outFile.open("addr_debug.txt");    outFile << "m_var init address: " << &m_var << endl;    PRINT_MSG_2SP("&m_var", &m_var);}void Detector::process(int *pIn, int *pOut, int n) {    outFile << "m_var process address: " << &m_var << endl;    outFile.close();    PRINT_MSG_2SP("&m_var", &m_var);}#define SIM_EXPORT __declspec(dllexport)#if defined(__cplusplus)extern "C" {#endif    SIM_EXPORT Detector *DetectorNew() { return new Detector(); }    SIM_EXPORT void DetectorProcess(Detector *pDet, int *pIn, int *pOut, int n) {        pDet->process(pIn, pOut, n);    }    SIM_EXPORT void DetectorDelete(Detector *pDet) { delete pDet; }#if defined(__cplusplus)}#endif

pre.py

import sysfrom ctypes import CDLL, POINTER,     c_int, c_void_pimport numpy as npsim_dll = CDLL("./sim.dll")detector_new_func = sim_dll.DetectorNewdetector_new_func.restype = c_void_pdetector_process_func = sim_dll.DetectorProcessdetector_process_func.argtypes = [c_void_p, POINTER(c_int), POINTER(c_int), c_int]detector_delete_func = sim_dll.DetectorDeletedetector_delete_func.argtypes = [c_void_p]class Detector():    def __init__(self):        self.obj = detector_new_func()    def process(self, pin, pout, n):        detector_process_func(self.obj, pin, pout, n)    def __del__(self):        detector_delete_func(self.obj)def main():    detector = Detector()    n = 1024    a = np.arange(n, dtype=np.uint32)    b = np.zeros(n, dtype=np.int32)    aptr = a.ctypes.data_as(POINTER(c_int))    bptr = b.ctypes.data_as(POINTER(c_int))    detector.process(aptr, bptr, n)if __name__ == "__main__":    print("Python {:s} on {:s}n".format(sys.version, sys.platform))    main()

注意事项

  • 正如我在开始时所说,问题是未指定 argtypesrestype (例如,对于 DetectorNew :comment
    detector_new_func.restype = c_void_p
    ,您将再次遇到问题)
  • 问题中的代码缺少部分( #includeimport ,…),还存在一些语法错误,因此它无法编译,因此不遵循[SO]:如何创建最小化,完整且可验证的示例(mcve)准则。请在询问时确保拥有 mcve
  • 您分配(
    new Detector()
    )的对象也必须被释放(否则,它将产生 内存泄漏 ),因此我添加了一个函数( DetectorDelete- 为此),该函数从( PythonDetector 的析构函数进行调用
  • 其他(非关键)更改(标识符重命名,一点重构,打印到 stdout 等)

输出

(py35x64_tes1)

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

(py35x64_test) e:WorkDevStackOverflowq052268294>dir /bpre.pydetector.cpp(py35x64_test) e:WorkDevStackOverflowq052268294>cl /nologo /DDLL

/EHsc detector.cpp /link /DLL /OUT:sim.dll
detector.cpp
Creating library sim.lib and object sim.exp

(py35x64_test) e:WorkDevStackOverflowq052268294>dir /bpre.pydetector.cppdetector.objsim.dllsim.expsim.lib(py35x64_test)

e:WorkDevStackOverflowq052268294>”e:WorkDevVEnvspy35x64_testscriptspython.exe”
./pre.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 - [detector.cpp] (28) - [Detector::Detector]:  &m_var:

0x0000020CE366E270
From C - [detector.cpp] (34) - [Detector::process]: &m_var:
0x0000020CE366E270



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

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

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