首页 > 解决方案 > 如何在python 2.7中返回带有ctypes的指针字符串

问题描述

我正在实施新的财政措施。它使用 OPOS / UPOS 库进行通信。我对 C 很陌生ctypes,完全没有使用 C 的经验。但是,我已经设法使它工作,主要是。

但是我在从通才方法返回字符串时遇到问题DirectIO。文档说:“应在 EndFiscalReceipt() 之后立即使用此命令来检索最新收据的唯一 ID”

" 参数:– 数据 [in] 被忽略。– Obj [in/out] 要读取的值。"

并在其下添加 .NET 示例:

int iData = 0;
string strReferenceID = "";
fiscalPrinter.EndFiscalReceipt();
fiscalPrinter.DirectIO(CMD_EKASA_RECEIPT_ID, ref iData, ref strReferenceID);
// strReferenceID will contain latest receipt ID, e.g. "O−7DBCDA8A56EE426DBCDA8A56EE426D1A"

第一个参数(CMD_EKASA_RECEIPT_ID)是执行的命令,这就是上面没有列出的原因。

但是,python 不是 .NET,我从未使用过 .NET。

我一直在遵循 ctypes doku ( https://docs.python.org/2.7/library/ctypes.html ) 中的说明,拒绝此方法参数并在 init 中返回:

self.libc.DirectIO.argtypes = [ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p]
self.libc.DirectIO.restype = ctypes.c_char_p

比尝试不同的方法来检索回复字符串,但这些都不适用于我的情况:

s = ""
c_s = ctypes.c_char_p(s)
result = self.send_command(CMD_EKASA_RECEIPT_ID, 0, c_s)

p = ctypes.create_string_buffer(40)
poin = ctypes.pointer(p)
result = self.send_command(CMD_EKASA_RECEIPT_ID, 0, poin)

p = ctypes.create_string_buffer(40)
result = self.send_command(CMD_EKASA_RECEIPT_ID, 0, p)

s = ctypes.create_string_buffer('\000' * 32)
result = self.send_command(CMD_EKASA_RECEIPT_ID, 0, s)

我创建的字符串对象总是空的,也就是""在调用 Cmethod 之后,就像我创建它一样。

但是,还有一件事,对我来说没有意义。我的同事向我展示了如何查看方法参数并在头文件中返回。对于这个,有这个:

int DirectIO(int iCommand, int* piData, const char* pccString);

这意味着,它返回整数?如果我没有记错的话。

所以,我在想的是,我必须将一些指向字符串的指针传递给该方法,该字符串是在 python 中创建的,C 会将其更改为我应该阅读的内容。因此,我认为我对解决方案的思考方式是正确的。

我也尝试过这种方法,但这对我也不起作用How to pass pointer back in ctypes?

我开始感到绝望。不确定我是否正确理解问题并寻找解决方案是正确的地方。

标签: linuxpython-2.7ctypes

解决方案


标签中有linux,但OPOS在linux上不起作用。

或者您是否在 Wine 等仿真环境中工作?

无论如何,如果您没有合适的环境,您可能会陷入困境。

首先,在 Windows 32 位环境中工作,创建在那里工作的东西,然后将其移植到另一个环境。

由于 OPOS 使用 OLE/COM 技术,所以第一个使用的包是win32comor comtypes


UnifiedPOS 是一个概念规范,没有实际的软件组件。

实际运行的软件有三种类型:OPOS、JavaPOS 和 POS for.NET。
OPOS 和 POS for.NET 只能在 Windows 32 位环境中工作。

只有 JavaPOS 可以在 Linux 环境中工作,而且通常只能从 Java 中获得。

如果你想用 Python 做一些事情,你需要创建一个从 Python 调用 Java 的 Wrapper(或胶水)库。


如果 C 接口 UnifiedPOS(OPOS) 在 Linux 上运行而没有使用 Windows 模拟器或 Wrapper for Java,它可能是打印机供应商参考 UnifiedPOS 创建的原始库/组件。

在这种情况下,我认为只能从创建它的供应商那里听到详细的规范。


解释一下,DirectIO方法和DirectIOEvent被定义为厂商可以自由定义和使用的方法/事件。

因此,UnifiedPOS 文档中只定义了方法/事件名称和参数。

需要询问提供DirectIO方法/DirectIOEvent的厂商,具体厂商的服务对象有什么功能,由厂商决定参数的含义。

OPOS 规范从中间被 UnifiedPOS 吸收,但在此之前它作为单一规范存在。

其余的名字在这里。 MCS:OPOS 发布

这是您的库方法的返回值是整数的根。

顺便说一句,这是目前最新的 UnifiedPOS 规范。
文档 --retail/17-07-32(UnifiedPOS 零售外设架构,版本 1.14.1)


推荐阅读