如何在python 2.7中使用ctypes返回指针字符串

我正在实施新的财务设备。并且它使用OPOS / UPOS库进行通信。我是#r "Newtonsoft.Json" using System.Net; using microsoft.AspNetCore.Mvc; using microsoft.Extensions.Primitives; using Newtonsoft.Json; using System.IO; using System.Collections.Generic; public static void Run(HttpRequest req,Stream inputBlob,ILogger log) { StreamReader reader = new StreamReader(inputBlob); string oldContent = reader.ReadToEnd(); log.LogInformation($"oldContent:{oldContent}"); } 的新手,完全没有C的经验。但是,大多数情况下,我设法使它起作用。

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

“参数:  –数据[输入]  忽略了。  –对象[输入/输出]  要读取的值。”

并在其下添加.NET示例:

DirectIO

第一个参数(CMD_EKASA_RECEIPT_ID)是执行的命令,这就是为什么它不在上面列出的原因。

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

我一直按照ctypes doku(

如何在python 2.7中使用ctypes返回指针字符串

)中的说明进行操作,违抗此方法的参数并返回init:

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"

我们尝试了不同的方法来检索回复字符串,但是在我的情况下,这两种方法都不起作用:

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

我创建的字符串对象在校准Cmethod之后始终为空,也就是s = "" c_s = ctypes.c_char_p(s) result = self.send_command(CMD_EKASA_RECEIPT_ID,c_s) p = ctypes.create_string_buffer(40) poin = ctypes.pointer(p) result = self.send_command(CMD_EKASA_RECEIPT_ID,poin) p = ctypes.create_string_buffer(40) result = self.send_command(CMD_EKASA_RECEIPT_ID,p) s = ctypes.create_string_buffer('\000' * 32) result = self.send_command(CMD_EKASA_RECEIPT_ID,s) ,就像我创建它一样。

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

""

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

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

我也尝试过这种方法,但是https://docs.python.org/2.7/library/ctypes.html

对我也不起作用

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

zhuhao568 回答:如何在python 2.7中使用ctypes返回指针字符串

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

还是您在类似Wine的仿真环境中工作?

在任何情况下,如果您没有正确的环境,都可能一无所获。

首先,在Windows 32位环境中工作,创建在此处可以工作的内容,然后将其移植到另一个环境。

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


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

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

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

如果要用Python制作东西,则需要创建一个Wrapper(或粘胶)库,该库从Python调用Java。


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

在这种情况下,我认为详细规范只能从创建它的供应商处获得。


为说明起见,DirectIO方法和DirectIOEvent被定义为供应商可以自由定义和使用的方法/事件。

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

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

OPOS规范从中间就被UnifiedPOS吸收,但是直到那时它还是作为一个规范存在的。

其余的名称在这里。 MCS: OPOS Releases

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

顺便说一下,这是目前最新的UnifiedPOS规范。
Document -- retail/17-07-32 (UnifiedPOS Retail Peripheral Architecture,Version 1.14.1)

,

我已经解决了我的问题。整个过程是在分配内存中。我在网上阅读的每个示例都创建了一个空字符串,例如s = ""。但是,那是不正确的!

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

这几乎是正确的方法,

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,result_s)
log.info('S address: %s | S.value: "%s"' % (result_s,result_s.value))

返回:

S address: c_char_p(140192115373700) | S.value: ""
S address: c_char_p(140192115373700) | S.value: ""

它仅需进行少量修改:

self.libc = ctypes.cdll.LoadLibrary(LIB_PATH)
self.libc.DirectIO.argtypes = [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)
log.info('S address: %s | S.value: %s' % (result_s,result_s.value))

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

S address: c_char_p(140532072777764) | S.value: "          "
S address: c_char_p(140532072777764) | S.value: "0-C12A22F5"
本文链接:https://www.f2er.com/3144961.html

大家都在问