So, I am writing a programm for my business that would basically be a cash register. Don't know for other countries but here in Russia the tax law works like this: you have to form a check for a customer in a spicific way spicified by the law, so some hardware manufacturers are making certified cash registers/check printers that simply form the check needed and automatically send tax info to authorities, very simple and easy to integrate with ERP systems. The only problem is that most of accounting software that is compatible with those registers is written for Windows. Now that Windows becomes more and more monstrous, many businesses turn to Linux, at least on those computers that are only a cashier's workstation that does not need to do much in terms of performance power. But the problem is, there's only one or two cashier's programms for linux exist for now, that are compatible with that certified hardware, and it's not open source or free.

First of all I want to make my own for myself, and second - I want to share it. Gambas is a great language in this case because of many aspects. In small buisnesses usually there are not a lot of qualified programmers to make some apps in C or C++, but instead there usually is just a single sysadmin, who is servicing the IT stuff wich usually is just one or two PCs and a router/switch. So, Gambas is much more accessible to those people as I see it. Programs written on it are easy to understand and modify to the needs of a small business.


And what is great - the manufacturers of that certified hardware are willing to help: ofcourse they mostly do business with Windows stuff, they only work directly with big businesses and they don't produce accounting software themselves, but they are kind enough to provide at least a binary libraries (they call those - drivers, but i'm not shure if it's technically correct) for their hardware even for Linux as a x86 and x64 .so files. What those binary libraries do is simple conversion of easy commands to hex codes that are then passed to a hardware via USB or RS232 or Ethernet. It is MUCH easier to work with those commands then implement the whole communication protocol from scratch. Ofcourse I am not the only one who is interested in those devices to work under linux, and as I can tell from different forums in the internet - programmers successfully use this libraries and thank the developers. There's not a lot of documentation out there, but yeah, on paper it seems to be simple enough... if you write your code in C or C++.


Things get much different when you try to use the library in Gambas. What I was able to understand from the documentation is that you need to "initialize the interface" with the library, which will create a "virtual class" and than you can pass your data to it. So, in C (using QT) that would look something like this:


 typedef IFptr * (*_CreateFptrInterface)(int ver);

    bool init() {
        QLibrary *lib = new QLibrary("fptr");
        lib->load();
        if(lib->isLoaded()) {
_CreateFptrInterface CreateFptrInterface = (_CreateFptrInterface)lib->resolve("CreateFptrInterface");
            if(CreateFptrInterface) {
                IFptr * iface = CreateFptrInterface(12);
                iface->put_DeviceEnabled(true);
                int result = 0;
                iface->get_ResultCode(&result);
                qDebug() << result;
                wchar_t bfr[1000];
                int length = iface->get_ResultDescription(bfr,1000);
                qDebug() << QString::fromWCharArray(bfr,length);
            }
        }
    }


So, as I understand we create a pointer called IFptr by calling CreateFptrInterface() and then we pass any other pointer through this one. Pardon my terminology, I am new to this stuff.

I wrote some simple code that basically initializes this driver just so I can see some output in the driver logs which are kindly created in ~/.atol. It also sends some data to driver which must change just one setting:

-----

Library "~/ATOL/linux-x64/libfptr"

Extern CreateFptrInterface(ver As Integer) As Pointer
Extern put_DeviceSingleSettingAsInt(p As Pointer, s1 As String, s2 As Integer) As Integer
Extern ApplySingleSettings(p As Pointer) As Pointer

[...]

Public Sub Button1_Click()
Dim IFptr As Pointer

IFptr = CreateFptrInterface(12)
put_DeviceSingleSettingAsInt(IFptr, "Model", 63)

ApplySingleSettings(IFptr)

End

-----

When I click Button1, the driver surely initializes, I see in logs that IFptr object is created. If I provide the wrong version in CreateFptrInterface it fails, saying in logs that there's missmatch in interface version, so no doubt the argument is passed correctly. I also can see that put_DeviceSingleSetting is being called, but the configuration does not actually change. The commercial software that uses this very same driver and works fine - leaves mostly the same trace in driver's log except that I see what arguments are passed to DeviceSingleSetting. And in my case I only see that the procedure is envoked but with no arguments. I was trying to use many other procedures (or methods, or pointers, or what are they?) with the same effect - they surely are called and executed, but I can't pass any arguments to them. I was experimenting with variable types I send them, and if I, for example, send an integer as an argument when the library expects a string - it crashes. If I do not use IFptr pointer - it crashes. So I think I figured out the syntax correctly, but I still can't get the desired result.


My question is basically this: Should I continue experimenting, or is it simply impossible to work with this kind of library from Gambas?


Here is the link to the library and some other libraries it uses itself: http://allunix.ru/back/atol.tar.gz - there's also a binary executable that is a test program, unfortunately it's in Russian, but it still shows what logs must look like when everything is correct, just for a comparison.


There's simple experiment you can make: it has a pointer ShowProperties() which must show a window with driver's settings using it's own library libgui_engine.so. When I call ShowProperties(IFptr) it prints to log that it can't find this lib, which is expectable, because first I must provide the path to it using put_DeviceSingleSettingAsBuff(IFptr, "SearchDir", "/home/bocha/ATOL/linux-x64/") and AplySingleSettings(IFptr), but when I pass this setting, I, as always, see that it passes no arguments, so the result stays the same.

I do understand that I ask a lot of invovement, there's no simple way to understand what's needed to be done to make this whole thing work so not many people would even read this message to the end, but I still hope for some answers, they would be much appriciated. Thank you!

Best Regards.

Dmitry Bachilo.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user

Reply via email to