首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在python 2.7中返回带有ctype的指针字符串

如何在python 2.7中返回带有ctype的指针字符串
EN

Stack Overflow用户
提问于 2019-11-07 12:13:50
回答 2查看 136关注 0票数 0

我正在努力实施新的财政手段。它使用OPOS / UPOS库进行通信。我是ctypes的新手,一点C的经验都没有。然而,我已经设法使它发挥作用,大部分。

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

“参数:-被忽略的数据。-要读取的值/输出值。”

并在它下面添加了.NET示例:

代码语言:javascript
复制
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 (https://docs.python.org/2.7/library/ctypes.html)中的说明,使用此方法参数并在init中返回:

代码语言:javascript
复制
self.libc.DirectIO.argtypes = [ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p]
self.libc.DirectIO.restype = ctypes.c_char_p

而不是尝试不同的方法来检索回复字符串,但在我的例子中,这两种方法都不起作用:

代码语言:javascript
复制
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)

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

然而,还有一件事,对我来说毫无意义。我的同事向我展示了如何在头文件中看到方法参数并返回。对于这个问题,有以下几点:

代码语言:javascript
复制
int DirectIO(int iCommand, int* piData, const char* pccString);

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

所以,我想的是,我必须把一些指向字符串的指针传递给方法,这个字符串是用python创建的,C会把它修改成我应该读的东西。因此,我认为我对解决方案的思考是正确的。

我也尝试过这种方法,但这对我来说也不适用,如何在ctype中传递指针?

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

EN

回答 2

Stack Overflow用户

发布于 2019-11-07 14:31:45

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

或者您是在模拟环境中工作,比如葡萄酒?

在任何情况下,如果你没有合适的环境,你就会陷入麻烦。

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

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

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

实际运行的软件有三种: OPOS、JavaPOS和POS for.NET。

OPOS和POS for.NET只在32位环境中工作.

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

如果您想在Python中做些什么,您需要创建一个从Python调用Java的包装器(或胶水)库。

如果C接口UnifiedPOS(OPOS)在Linux上运行,而不使用UnifiedPOS仿真器或包装器,则它可能是打印机供应商参照UnifiedPOS创建的原始库/组件。

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

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

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

有必要询问提供DirectIO方法/DirectIOEvent的供应商特定供应商的服务对象具有什么功能,并由供应商来确定参数的含义。

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

剩下的名字在这里。监督事务司:业务执行干事发布

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

顺便说一下,这是目前最新的UnifiedPOS规范。

文档--零售/17-07-32 (UnifiedPOS零售外围架构,1.14.1版)

票数 0
EN

Stack Overflow用户

发布于 2019-11-08 09:27:04

我已经解决了我的问题。整件事就是在分配记忆。我所读过的网络上的每个示例都创建了空字符串,比如s = ""。但是,这是不对的!

当分配空字符串时,"" C库没有内存写入结果。

这几乎是正确的方法,

代码语言:javascript
复制
self.libc = ctypes.cdll.LoadLibrary(LIB_PATH)
self.libc.DirectIO.argtypes = [ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p]
result_s = ctypes.c_char_p("")
log.info('S address: %s | S.value: "%s"' % (result_s, result_s.value))
self.libc.DirectIO(CMD_EKASA_RECEIPT_ID, 0, result_s)
log.info('S address: %s | S.value: "%s"' % (result_s, result_s.value))

返回:

代码语言:javascript
复制
S address: c_char_p(140192115373700) | S.value: ""
S address: c_char_p(140192115373700) | S.value: ""

它只需要一个小小的修改:

代码语言:javascript
复制
self.libc = ctypes.cdll.LoadLibrary(LIB_PATH)
self.libc.DirectIO.argtypes = [ctypes.c_int32, ctypes.c_int32, ctypes.c_char_p]
result_s = ctypes.c_char_p(" " * 10)
log.info('S address: %s | S.value: %s' % (result_s, result_s.value))
self.libc.DirectIO(CMD_EKASA_RECEIPT_ID, 0, result_s)
log.info('S address: %s | S.value: %s' % (result_s, result_s.value))

现在,在调用result_s之后打印self.libc.DirectIO确实返回与调用前不同的字符串。

代码语言:javascript
复制
S address: c_char_p(140532072777764) | S.value: "          "
S address: c_char_p(140532072777764) | S.value: "0-C12A22F5"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58748571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档