在 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 库调用完成得太晚

Python—Numpy库的用法

来自 SVN 存储库的签出代码在 xcode 5 中出现错误

'_FCbuild'不能用作函数 - c / c ++代码错误