在 python 代码中处理来自 C 库的对象
Posted
技术标签:
【中文标题】在 python 代码中处理来自 C 库的对象【英文标题】:Handling objects from a C library in python code 【发布时间】:2020-04-23 05:21:38 【问题描述】:我想将.dll
文件中的 C/C++ 库实现为 Python 脚本,以控制名为 ClipX by HBM 的 I/O 设备(以防将来有人需要帮助)。
制造商提供了一个示例 C 实现和一个示例 C++ 实现。在 C 示例中,Connect() 函数返回一些指针,该指针用于后续的读/写函数。在 C++ 示例中,ClipX 类用于建立连接,而读/写函数是该类中的方法。为了这个问题,我已经简化了代码。
基本上,我想将connect()
发送到设备,稍后再发送read()
。根据我的阅读,Cython 似乎是将connect()
和read()
包装为单独的函数并将它们作为模块导入Python 的好方法。我的问题是:
对于 C 实现,我能否在连接后将 MHandle 指针传回 Python 以供以后使用(即调用 read 函数)?指针是否还有任何意义,稍后在不同的函数调用中使用?
对于 C++ 实现,是否可以将 dev 对象传递给 Python 代码,以便稍后传递回 Read()
?你可以用任意对象做到这一点吗?
我是一名机械工程师,如果这是胡言乱语或完全不了解情况,请见谅。非常感谢任何指导。
C 代码:
/*From .h file*/
----------------------------------------------------
struct sClipX
void *obj;
;
typedef struct sClipX * MHandle;
ClipX_API MHandle __stdcall Connect(const char *);
----------------------------------------------------
/*End .h file*/
int main()
const char * IP = "172.21.104.76";
MHandle m=Connect(IP);
Read(m, 0x4428);
C++ 代码:
int main()
ClipX dev = ClipX();
dev.Connect("172.21.104.76");
dev.Read(0x4428);
【问题讨论】:
你应该试试python C Foreign Function Interface link 请提供您要入侵的设备的 URL HBM ClipX 请不要评论您的问题,但请edit它 抱歉,我已经添加了 【参考方案1】:如果您将 C++ 函数声明为 extern "C"
,则可以从 C 中调用它们。这与name mangling有关
可以使用 C 函数扩展 Python 解释器。仔细阅读Extending and Embedding the Python Interpreter 章节。
小心 C++ 异常。您不希望它们跨越 Python 解释器代码。因此,任何从 Python 调用的 extern "C"
C++ 函数都应该处理并捕获由内部例程引发的 exceptions。
最后,要小心内存管理和垃圾收集。 P.Wilson 关于Uniprocessor garbage collection techniques 的旧论文是相关的,至少对于术语和见解而言。或阅读GC handbook。 Python 使用reference counting 方案并专门处理weak references。小心circular references。
当然要注意 Python 中的 GIL。粗略地说,你不能让多个线程在没有预防措施的情况下做 Python 的事情。
Serialization 的设备相关数据也是一个问题,但您可能不需要它。
最重要的是,很好地记录您的代码。
doxygen 之类的工具可能会有所帮助(可能使用 LaTeX 或 DocBook)。
当然要使用足够好的version control 系统。我推荐git。也是一个很好的build automation 工具。
我的建议是将您的 C++ 代码发布为 open source,例如在github 或gitlab 上。然后您可以获得有用的code reviews 和反馈。
如果您的硬件 + 软件系统是 safety-critical,请考虑 static program analysis 技术,例如与Frama-C 或Clang static analyzer 或您自己的GCC plugin。几个月后(2020 年底),您可能会尝试Bismon(另请阅读this draft 报告)。
我肯定有偏见,但我确实建议尝试一些 Linux distribution(例如 Ubuntu 或 Debian)作为您的交叉开发平台。请注意,许多设备(包括RaspBerryPi)都在运行一些embedded Linux system,因此学习努力是有意义的。然后阅读Advanced Linux Programming
【讨论】:
感谢您的详细回复和参考!我一定会调查他们。 我真的建议尝试 Linux 发行版。您可以向我发送电子邮件至basile@starynkevitch.net
以获得更多帮助,但请在您的电子邮件中提及您的问题的 URL以上是关于在 python 代码中处理来自 C 库的对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有来自 c 库的 printf 的情况下在汇编级编程中打印整数?
如何在没有来自 c 库的 printf 的情况下在汇编级编程中打印整数?
来自 C 代码的异步 javascript 库调用完成得太晚