C++ 接口问题使用 .NET POS SDK 进行 POS 控制
我们正在尝试实现一个支持 COM 接口来模拟 POSPrinter 但仍与旧技术兼容的 .NET 服务对象。
我们的接口和类对象位于以下类中。
using [...]
namespace yRPOSPrinterDotNet
{
[Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface yRPosPrinterCOM
{
long Open(String DeviceName);
long PrintNormal(long Station, String Data);
}
[Guid("478176F4-5105-435c-8EBC-D4CB90B7B1C7")]
[ClassInterface(ClassInterfaceType.None)]
//[ProgId("yRPOSPrinterDotNet.POSPrinter")] //will be set automatically as the progid <namespace><clsid>
public class POSPrinter : yRPosPrinterCOM
{
#region yRPosPrinterCOM Members
public long Open()
{
return 0;
}
public long Open(String DeviceName)
{
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
FileStream objStream = new FileStream("C:\\yRPOSLog.txt", FileMode.OpenOrCreate);
TextWriterTraceListener objTraceListener = new TextWriterTraceListener(objStream);
Trace.Listeners.Add(objTraceListener);
Trace.AutoFlush = true;
Trace.Indent();
Trace.WriteLine("Entering Main");
Debug.WriteLine("How does this one do??");
Console.WriteLine("Hello World.");
Trace.WriteLine("Exiting Main");
Trace.Unindent();
return 0;
}
public long PrintNormal(long Station, string Data)
{
throw new NotImplementedException();
}
#endregion
}
}
并将我们的 yRPosPrinterDotNet.POSPrinter ProgID 放入 HKEY_LOCAL_MACHINE\SOFTWARE\OLEforRetail\ServiceOPOS\POSPrinter\yReceipts
中
HKEY_CLASSES_ROOT\CLSID\{478176F4- 5105-435C-8EBC-D4CB90B7B1C7}
在构建后正确地具有我们的 ProgID (yRPosPrinterDotNet.POSPrinter)
我们可以使用此类通过测试类调用 DLL,如下所示(查找 ProgID)
using [...]
namespace TestYRPosPrinterDotNet
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1
{
public UnitTest1()
{
}
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestMethod]
public void TestMethod1()
{
String sProgID = "yRPosPrinterDotNet.POSPrinter";
// We get the type using just the ProgID
Type oType = Type.GetTypeFromProgID(sProgID);
if (oType != null)
{
POSPrinter pp = (POSPrinter)Activator.CreateInstance(oType);
long retVal = pp.Open("Nothing");
}
}
}
}
但是当我们尝试通过示例 TestApp 调用时(它确实显示为服务对象)
{"Method Open threw an exception. The service object does not support one or more of the methods required by its release."} System.Exception {Microsoft.PointOfService.PosControlException}
通过示例 C++ 控制对象,我们收到在 opos.h 中定义为 (const LONG OPOS_E_NOSERVICE = 4 + OPOSERR;)
的 104,其堆栈跟踪如下
----------------------------------- Doesn't work --------------------------------------------------------
POSPrinterExample.exe!COleDispatchDriver::InvokeHelperV(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, char * argList=0x0012f110) Line
397 C++
POSPrinterExample.exe!COleControlSite::InvokeHelperV(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, char * argList=0x0012f10c) Line 1093
C++
POSPrinterExample.exe!CWnd::InvokeHelper(long dwDispID=37, unsigned short wFlags=1, unsigned short vtRet=3, void * pvRet=0x0012f1e0, const unsigned char * pbParamInfo=0x00702014, ...) Line 382 C++
POSPrinterExample.exe!COPOSPOSPrinter::Open(const char * DeviceName=0x00271f00) Line 192 + 0x1c bytes C++
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这似乎是一个DispInterface。为了支持 Visual Basic,这是一个可怕的 COM 黑客攻击。基本上,所有功能都已编号。第一次调用时,将查找并缓存所有函数号。例如,您似乎缺少 Close() 函数。正如您所看到的,这将导致它查找失败。
引自《OLE for Retail POS Control Guide - Rel. 1.1》:
This seems to be a DispInterface. That's a horrible COM hack to support Visual Basic. Basically, all functions are numbered. On the first call, all function numbers are looked up and cached. It seems you are missing the Close() function, for instance. This would cause it to fail in lookup, in the way you see.
Quoting from "OLE for Retail POS Control Guide - Rel. 1.1" :