Working with .so library

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Working with .so library

Admin
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Caveat-2
Hallo Dmitry

Did you already look at:

http://gambaswiki.org/wiki/howto/extern ?

Kind regards,
Caveat

On 31-05-17 06:48, Admin wrote:

> 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
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>
>


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Benoît Minisini
In reply to this post by Admin
Le 31/05/2017 à 06:48, Admin a écrit :

> 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.
>

Apparently all that black box is written in C++ with QT, and without the
header of the library interface , I can't tell you if it is possible to
use the library with Gambas, and how.

Regards,

--
Benoît Minisini

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
In reply to this post by Caveat-2
Hi, Caveat.

Yes, ofcourse, this is basically the only article outthere that explains
at least something. But I still can't understand why arguments are not
sent to my lib and what do I do wrong if it's not the Gambas issue.

31.05.2017 16:35, Caveat пишет:

> Hallo Dmitry
>
> Did you already look at:
>
> http://gambaswiki.org/wiki/howto/extern ?
>
> Kind regards,
> Caveat
>
> On 31-05-17 06:48, Admin wrote:
>> 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
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/gambas-user
>>
>>
>
>
> ------------------------------------------------------------------------------
>
> 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
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>
>


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
In reply to this post by Benoît Minisini
31.05.2017 16:58, Benoît Minisini пишет:

> Le 31/05/2017 à 06:48, Admin a écrit :
>> 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.
>>
>
> Apparently all that black box is written in C++ with QT, and without
> the header of the library interface , I can't tell you if it is
> possible to use the library with Gambas, and how.
>
> Regards,
>
I was lucky enough to find the header file shared by developers and an
example program in C++ that utilizes this lib.

Here they are: http://allunix.ru/back/atol-header.tar.gz


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Benoît Minisini
Le 31/05/2017 à 12:38, Admin a écrit :

> 31.05.2017 16:58, Benoît Minisini пишет:
>> Apparently all that black box is written in C++ with QT, and without
>> the header of the library interface , I can't tell you if it is
>> possible to use the library with Gambas, and how.
>>
>> Regards,
>>
> I was lucky enough to find the header file shared by developers and an
> example program in C++ that utilizes this lib.
>
> Here they are: http://allunix.ru/back/atol-header.tar.gz
>

Maybe CreateFptrInterface() is a C++ only thing, and that you must call
another function from the C interface to do something similar. But I
couldn't find it reading the C header.

You need the documentation of the C interface, or at least an example
written in C to know. You usually can't use C++ exported functions from
Gambas.

Regards,

--
Benoît Minisini

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

PICCORO McKAY Lenz
hello all, the gambas extern documentation says how to create references
with simgle pointers like

  IFptr * iface = CreateFptrInterface(12);

but not with more complex for novice users like:

  struct fp_dscv_dev **discovered_devs;

i'm not expert in C and only few examples , some time ago i'v write a
libfprint interface but due dificult and poor documentation and poor
interes many linux users does not have a libfprint interface.. same
behaviour for odbc

i now understand why in guindows there so many users doing something..

Lenz McKAY Gerardo (PICCORO)
http://qgqlochekone.blogspot.com

2017-05-31 7:18 GMT-04:00 Benoît Minisini <[hidden email]>:

> Le 31/05/2017 à 12:38, Admin a écrit :
>
>> 31.05.2017 16:58, Benoît Minisini пишет:
>>
>>> Apparently all that black box is written in C++ with QT, and without the
>>> header of the library interface , I can't tell you if it is possible to use
>>> the library with Gambas, and how.
>>>
>>> Regards,
>>>
>>> I was lucky enough to find the header file shared by developers and an
>> example program in C++ that utilizes this lib.
>>
>> Here they are: http://allunix.ru/back/atol-header.tar.gz
>>
>>
> Maybe CreateFptrInterface() is a C++ only thing, and that you must call
> another function from the C interface to do something similar. But I
> couldn't find it reading the C header.
>
> You need the documentation of the C interface, or at least an example
> written in C to know. You usually can't use C++ exported functions from
> Gambas.
>
> Regards,
>
> --
> Benoît Minisini
>
>
> ------------------------------------------------------------
> ------------------
> 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
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>
------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
In reply to this post by Benoît Minisini
31.05.2017 18:18, Benoît Minisini пишет:

> Le 31/05/2017 à 12:38, Admin a écrit :
>> 31.05.2017 16:58, Benoît Minisini пишет:
>>> Apparently all that black box is written in C++ with QT, and without
>>> the header of the library interface , I can't tell you if it is
>>> possible to use the library with Gambas, and how.
>>>
>>> Regards,
>>>
>> I was lucky enough to find the header file shared by developers and
>> an example program in C++ that utilizes this lib.
>>
>> Here they are: http://allunix.ru/back/atol-header.tar.gz
>>
>
> Maybe CreateFptrInterface() is a C++ only thing, and that you must
> call another function from the C interface to do something similar.
> But I couldn't find it reading the C header.
>
> You need the documentation of the C interface, or at least an example
> written in C to know. You usually can't use C++ exported functions
> from Gambas.
>
> Regards,
>
Maybe it is. One of the authors of the original .so library stated on
one forum:

"You can use purely C interface like this:

void *fptr = CreateFptrInterface();
put_DeviceSingleSetting(fptr, L"Port", "4");
ApplySingleSettings(fptr);

"

but I can't see the difference.


Dmitry.

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Benoît Minisini
Le 31/05/2017 à 14:36, Admin a écrit :

> 31.05.2017 18:18, Benoît Minisini пишет:
>> Le 31/05/2017 à 12:38, Admin a écrit :
>>> 31.05.2017 16:58, Benoît Minisini пишет:
>>>> Apparently all that black box is written in C++ with QT, and without
>>>> the header of the library interface , I can't tell you if it is
>>>> possible to use the library with Gambas, and how.
>>>>
>>>> Regards,
>>>>
>>> I was lucky enough to find the header file shared by developers and
>>> an example program in C++ that utilizes this lib.
>>>
>>> Here they are: http://allunix.ru/back/atol-header.tar.gz
>>>
>>
>> Maybe CreateFptrInterface() is a C++ only thing, and that you must
>> call another function from the C interface to do something similar.
>> But I couldn't find it reading the C header.
>>
>> You need the documentation of the C interface, or at least an example
>> written in C to know. You usually can't use C++ exported functions
>> from Gambas.
>>
>> Regards,
>>
> Maybe it is. One of the authors of the original .so library stated on
> one forum:
>
> "You can use purely C interface like this:
>
> void *fptr = CreateFptrInterface();
> put_DeviceSingleSetting(fptr, L"Port", "4");
> ApplySingleSettings(fptr);
>
> "
>
> but I can't see the difference.
>
>
> Dmitry.
>

Then it should work the way you did. But you did not respect the
interface of put_DeviceSingleSettingAsInt(). It wants a "wchar_t *",
whereas the Gambas strings are encoded in ASCII or UTF-8.

You must first convert the Gambas string to wchar_t by using
Conv$(<string>, "UTF-8", "WCHAR_T") or Conv$(<string>, "ASCII", "WCHAR_T").

Regards,

--
Benoît Minisini

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
31.05.2017 19:50, Benoît Minisini пишет:

> Le 31/05/2017 à 14:36, Admin a écrit :
>> 31.05.2017 18:18, Benoît Minisini пишет:
>>> Le 31/05/2017 à 12:38, Admin a écrit :
>>>> 31.05.2017 16:58, Benoît Minisini пишет:
>>>>> Apparently all that black box is written in C++ with QT, and
>>>>> without the header of the library interface , I can't tell you if
>>>>> it is possible to use the library with Gambas, and how.
>>>>>
>>>>> Regards,
>>>>>
>>>> I was lucky enough to find the header file shared by developers and
>>>> an example program in C++ that utilizes this lib.
>>>>
>>>> Here they are: http://allunix.ru/back/atol-header.tar.gz
>>>>
>>>
>>> Maybe CreateFptrInterface() is a C++ only thing, and that you must
>>> call another function from the C interface to do something similar.
>>> But I couldn't find it reading the C header.
>>>
>>> You need the documentation of the C interface, or at least an
>>> example written in C to know. You usually can't use C++ exported
>>> functions from Gambas.
>>>
>>> Regards,
>>>
>> Maybe it is. One of the authors of the original .so library stated on
>> one forum:
>>
>> "You can use purely C interface like this:
>>
>> void *fptr = CreateFptrInterface();
>> put_DeviceSingleSetting(fptr, L"Port", "4");
>> ApplySingleSettings(fptr);
>>
>> "
>>
>> but I can't see the difference.
>>
>>
>> Dmitry.
>>
>
> Then it should work the way you did. But you did not respect the
> interface of put_DeviceSingleSettingAsInt(). It wants a "wchar_t *",
> whereas the Gambas strings are encoded in ASCII or UTF-8.
>
> You must first convert the Gambas string to wchar_t by using
> Conv$(<string>, "UTF-8", "WCHAR_T") or Conv$(<string>, "ASCII",
> "WCHAR_T").
>
> Regards,
>
Oh. My. God. That's exactly what I needed.

Actually, I saw that the library expetcs a variable in wchar_t format, I
had no idea what it was, so I googled "gambas wchar_t" and found
absolutely nothing. Then I wrote my first letter to this maillist.

And now when you gave me this line of the code, the library works
exactly the way it should, doing everything I'm asking it for.

Huge thank you!

Dmitry/


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
01.06.2017 16:25, Admin пишет:

> 31.05.2017 19:50, Benoît Minisini пишет:
>> Le 31/05/2017 à 14:36, Admin a écrit :
>>> 31.05.2017 18:18, Benoît Minisini пишет:
>>>> Le 31/05/2017 à 12:38, Admin a écrit :
>>>>> 31.05.2017 16:58, Benoît Minisini пишет:
>>>>>> Apparently all that black box is written in C++ with QT, and
>>>>>> without the header of the library interface , I can't tell you if
>>>>>> it is possible to use the library with Gambas, and how.
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>> I was lucky enough to find the header file shared by developers
>>>>> and an example program in C++ that utilizes this lib.
>>>>>
>>>>> Here they are: http://allunix.ru/back/atol-header.tar.gz
>>>>>
>>>>
>>>> Maybe CreateFptrInterface() is a C++ only thing, and that you must
>>>> call another function from the C interface to do something similar.
>>>> But I couldn't find it reading the C header.
>>>>
>>>> You need the documentation of the C interface, or at least an
>>>> example written in C to know. You usually can't use C++ exported
>>>> functions from Gambas.
>>>>
>>>> Regards,
>>>>
>>> Maybe it is. One of the authors of the original .so library stated
>>> on one forum:
>>>
>>> "You can use purely C interface like this:
>>>
>>> void *fptr = CreateFptrInterface();
>>> put_DeviceSingleSetting(fptr, L"Port", "4");
>>> ApplySingleSettings(fptr);
>>>
>>> "
>>>
>>> but I can't see the difference.
>>>
>>>
>>> Dmitry.
>>>
>>
>> Then it should work the way you did. But you did not respect the
>> interface of put_DeviceSingleSettingAsInt(). It wants a "wchar_t *",
>> whereas the Gambas strings are encoded in ASCII or UTF-8.
>>
>> You must first convert the Gambas string to wchar_t by using
>> Conv$(<string>, "UTF-8", "WCHAR_T") or Conv$(<string>, "ASCII",
>> "WCHAR_T").
>>
>> Regards,
>>
> Oh. My. God. That's exactly what I needed.
>
> Actually, I saw that the library expetcs a variable in wchar_t format,
> I had no idea what it was, so I googled "gambas wchar_t" and found
> absolutely nothing. Then I wrote my first letter to this maillist.
>
> And now when you gave me this line of the code, the library works
> exactly the way it should, doing everything I'm asking it for.
>
> Huge thank you!
>
> Dmitry
>

Greetings again.

All your help was very important for me, I now have completed my cash
register software to the point where it does everything my company
needs. I must say Gambas is a great language, it's very easy to learn
from scratch, I'm surprised how obvious everything is. But there is a
lot of work for me left to do mostly in terms of managing wrong human
actions. My software works good if the employee doesn't do any mistakes,
but that's unrealistic, so there's a lot of things I want to control and
check. And that's where I'm stuck.

This library (which still calls itself a driver) theoretically is able
to return a lot of values that I need, but I can't understand basic
rules of how do we take output from a C-lib in Gambas.

 From http://gambaswiki.org/wiki/howto/extern I understood that I need
to locate a space in memory and pass a pointer to a library so that it
can write data into that place in ram, which I would then read and set free.

So I have to declare a pointer, then Alloc(8) it, then pass it to my
library and then read from it like it is a stream. Does this principle
still work in current version of Gambas?

What I don't understand is how I construct the code in my particular case.

To make an interface to the library I declare external pointer like this:

     Extern CreateFptrInterface(ver As Integer) As Pointer

Then I declare some pointers that I'll use with help of the interface I
created:

     Extern put_DeviceEnable(p as Pointer, mode as Integer)

     Extern GetStatus(p as Pointer, StatRequest as String)

Then I declare the pointer which will be that interface:

     Public kkmDrv as Pointer

So then in sub I can do

kkmDrv = CreateFptrInterface(12) ' this establishes the interface

put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the library
through the interface.

And it works great.

But then If I want to get some data from the library, as I understand, I
have to declare another pointer, allocate ram for it and pass my request.

I don't understand how should I pass that pointer to GetStatus() while
also passing my interface pointer to it, let alone reading data back.
Totally confused.

Any advice would be much appriciated. I don't desperately need to listen
to my library, it's almost enough just to talk to it one way, but this
ability could make my software much more reliable and self-controlled,
so I really wish I could hear my library back.

Best regards.

Dmitry.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Tobias Boege-2
> All your help was very important for me, I now have completed my cash
> register software to the point where it does everything my company needs. I
> must say Gambas is a great language, it's very easy to learn from scratch,
> I'm surprised how obvious everything is. But there is a lot of work for me
> left to do mostly in terms of managing wrong human actions. My software
> works good if the employee doesn't do any mistakes, but that's unrealistic,
> so there's a lot of things I want to control and check. And that's where I'm
> stuck.
>
> This library (which still calls itself a driver) theoretically is able to
> return a lot of values that I need, but I can't understand basic rules of
> how do we take output from a C-lib in Gambas.
>
> From http://gambaswiki.org/wiki/howto/extern I understood that I need to
> locate a space in memory and pass a pointer to a library so that it can
> write data into that place in ram, which I would then read and set free.
>
> So I have to declare a pointer, then Alloc(8) it, then pass it to my library
> and then read from it like it is a stream. Does this principle still work in
> current version of Gambas?
>

If you do Alloc(8), then you get 8 bytes of memory. You most likely *don't*
want to read that like a stream, but use Integer@() or similar functions.

> What I don't understand is how I construct the code in my particular case.
>
> To make an interface to the library I declare external pointer like this:
>
>     Extern CreateFptrInterface(ver As Integer) As Pointer
>
> Then I declare some pointers that I'll use with help of the interface I
> created:
>
>     Extern put_DeviceEnable(p as Pointer, mode as Integer)
>
>     Extern GetStatus(p as Pointer, StatRequest as String)
>
> Then I declare the pointer which will be that interface:
>
>     Public kkmDrv as Pointer
>
> So then in sub I can do
>
> kkmDrv = CreateFptrInterface(12) ' this establishes the interface
>
> put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the library
> through the interface.
>
> And it works great.
>
> But then If I want to get some data from the library, as I understand, I
> have to declare another pointer, allocate ram for it and pass my request.
>
> I don't understand how should I pass that pointer to GetStatus() while also
> passing my interface pointer to it, let alone reading data back. Totally
> confused.
>

This entirely depends on how the C functions in your library are declared.
I don't know about your specific library but commonly the occurence of an
error is indicated by an integer return code, e.g. this might be the
signature of one of the functions in your library:

  int myfunction(void *interface, int argument)

If the documentation says that the return value (int) of this function
indicates an error, then you just need to get that return value back into
your Gambas program, which you accomplish by declaring the function in
Gambas as

  Extern myfunction(interface As Pointer, argument As Integer) As Integer

(notice the trailing "As Integer"). Then you can use "myfunction" in your
Gambas code like any other function and get and interpret its return value.

So, if this convention for error reporting is used, it is much simpler to
get information about errors, without using Alloc() and co. Your library
may use a different convention which actually involves pointers, but
I wouldn't know.

Regards,
Tobi

--
"There's an old saying: Don't change anything... ever!" -- Mr. Monk

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
15.06.2017 16:19, Tobias Boege пишет:

>> All your help was very important for me, I now have completed my cash
>> register software to the point where it does everything my company needs. I
>> must say Gambas is a great language, it's very easy to learn from scratch,
>> I'm surprised how obvious everything is. But there is a lot of work for me
>> left to do mostly in terms of managing wrong human actions. My software
>> works good if the employee doesn't do any mistakes, but that's unrealistic,
>> so there's a lot of things I want to control and check. And that's where I'm
>> stuck.
>>
>> This library (which still calls itself a driver) theoretically is able to
>> return a lot of values that I need, but I can't understand basic rules of
>> how do we take output from a C-lib in Gambas.
>>
>>  From http://gambaswiki.org/wiki/howto/extern I understood that I need to
>> locate a space in memory and pass a pointer to a library so that it can
>> write data into that place in ram, which I would then read and set free.
>>
>> So I have to declare a pointer, then Alloc(8) it, then pass it to my library
>> and then read from it like it is a stream. Does this principle still work in
>> current version of Gambas?
>>
> If you do Alloc(8), then you get 8 bytes of memory. You most likely *don't*
> want to read that like a stream, but use Integer@() or similar functions.
>
>> What I don't understand is how I construct the code in my particular case.
>>
>> To make an interface to the library I declare external pointer like this:
>>
>>      Extern CreateFptrInterface(ver As Integer) As Pointer
>>
>> Then I declare some pointers that I'll use with help of the interface I
>> created:
>>
>>      Extern put_DeviceEnable(p as Pointer, mode as Integer)
>>
>>      Extern GetStatus(p as Pointer, StatRequest as String)
>>
>> Then I declare the pointer which will be that interface:
>>
>>      Public kkmDrv as Pointer
>>
>> So then in sub I can do
>>
>> kkmDrv = CreateFptrInterface(12) ' this establishes the interface
>>
>> put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the library
>> through the interface.
>>
>> And it works great.
>>
>> But then If I want to get some data from the library, as I understand, I
>> have to declare another pointer, allocate ram for it and pass my request.
>>
>> I don't understand how should I pass that pointer to GetStatus() while also
>> passing my interface pointer to it, let alone reading data back. Totally
>> confused.
>>
> This entirely depends on how the C functions in your library are declared.
> I don't know about your specific library but commonly the occurence of an
> error is indicated by an integer return code, e.g. this might be the
> signature of one of the functions in your library:
>
>    int myfunction(void *interface, int argument)
>
> If the documentation says that the return value (int) of this function
> indicates an error, then you just need to get that return value back into
> your Gambas program, which you accomplish by declaring the function in
> Gambas as
>
>    Extern myfunction(interface As Pointer, argument As Integer) As Integer
>
> (notice the trailing "As Integer"). Then you can use "myfunction" in your
> Gambas code like any other function and get and interpret its return value.
>
> So, if this convention for error reporting is used, it is much simpler to
> get information about errors, without using Alloc() and co. Your library
> may use a different convention which actually involves pointers, but
> I wouldn't know.
>
> Regards,
> Tobi
>
I should've said it in the beginning. Ofcourse any function returns
integer value of 0 as success or -1 as error, but that only indicates
that function was successfully executed or not. So GetStatus() will
always return 0 because it shurely ran, nothing can go wrong here. But
that's not the result I want. GetStatus() actually gives back a string
with the status I asked for. Not that I fully understand how it does
that. I already gave links to the libfptr.so library itself
(http://allunix.ru/back/atol.tar.gz) and it's header files
(http://allunix.ru/back/atol-header.tar.gz) so that it's clearer, what
I'm talking about, unfortunately I am absolute zero in C to figure
things out myself.

For example I can see that to get serial number of the device driven by
that library i can use a function described like this:

get_SerialNumber(void *ptr, wchar_t *bfr, int bfrSize);

As far as I can tell what it does is it gets data needed and puts it
into some buffer. The result of executing this function through
put_SerialNumber(kkmDrv) will always be returned to me as 0.

So to see what's in that buffer, I have to then invoke GetStatus(kkmDrv)
describe in .h file like GetStatus(void *ptr); and the integer result of
this operation will also always be 0, which means that GetStatus itself
ran successfully, but I don't care about that, I want to see what it
actually told me, not that if it told me it successfully or not. So
that's the main confusion. If all this is too complicated and lamely
explained then nevermind, I expect it to be so and I'm sorry, that's the
best I can do. I'm just really confused that I recieve two answers, one
boolean telling if function successfully invoked and one string,
carrying the actual data I want.


Best Regards,

Dmitry.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Admin
15.06.2017 17:54, Admin пишет:

> 15.06.2017 16:19, Tobias Boege пишет:
>>> All your help was very important for me, I now have completed my cash
>>> register software to the point where it does everything my company
>>> needs. I
>>> must say Gambas is a great language, it's very easy to learn from
>>> scratch,
>>> I'm surprised how obvious everything is. But there is a lot of work
>>> for me
>>> left to do mostly in terms of managing wrong human actions. My software
>>> works good if the employee doesn't do any mistakes, but that's
>>> unrealistic,
>>> so there's a lot of things I want to control and check. And that's
>>> where I'm
>>> stuck.
>>>
>>> This library (which still calls itself a driver) theoretically is
>>> able to
>>> return a lot of values that I need, but I can't understand basic
>>> rules of
>>> how do we take output from a C-lib in Gambas.
>>>
>>>  From http://gambaswiki.org/wiki/howto/extern I understood that I
>>> need to
>>> locate a space in memory and pass a pointer to a library so that it can
>>> write data into that place in ram, which I would then read and set
>>> free.
>>>
>>> So I have to declare a pointer, then Alloc(8) it, then pass it to my
>>> library
>>> and then read from it like it is a stream. Does this principle still
>>> work in
>>> current version of Gambas?
>>>
>> If you do Alloc(8), then you get 8 bytes of memory. You most likely
>> *don't*
>> want to read that like a stream, but use Integer@() or similar
>> functions.
>>
>>> What I don't understand is how I construct the code in my particular
>>> case.
>>>
>>> To make an interface to the library I declare external pointer like
>>> this:
>>>
>>>      Extern CreateFptrInterface(ver As Integer) As Pointer
>>>
>>> Then I declare some pointers that I'll use with help of the interface I
>>> created:
>>>
>>>      Extern put_DeviceEnable(p as Pointer, mode as Integer)
>>>
>>>      Extern GetStatus(p as Pointer, StatRequest as String)
>>>
>>> Then I declare the pointer which will be that interface:
>>>
>>>      Public kkmDrv as Pointer
>>>
>>> So then in sub I can do
>>>
>>> kkmDrv = CreateFptrInterface(12) ' this establishes the interface
>>>
>>> put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the library
>>> through the interface.
>>>
>>> And it works great.
>>>
>>> But then If I want to get some data from the library, as I
>>> understand, I
>>> have to declare another pointer, allocate ram for it and pass my
>>> request.
>>>
>>> I don't understand how should I pass that pointer to GetStatus()
>>> while also
>>> passing my interface pointer to it, let alone reading data back.
>>> Totally
>>> confused.
>>>
>> This entirely depends on how the C functions in your library are
>> declared.
>> I don't know about your specific library but commonly the occurence
>> of an
>> error is indicated by an integer return code, e.g. this might be the
>> signature of one of the functions in your library:
>>
>>    int myfunction(void *interface, int argument)
>>
>> If the documentation says that the return value (int) of this function
>> indicates an error, then you just need to get that return value back
>> into
>> your Gambas program, which you accomplish by declaring the function in
>> Gambas as
>>
>>    Extern myfunction(interface As Pointer, argument As Integer) As
>> Integer
>>
>> (notice the trailing "As Integer"). Then you can use "myfunction" in
>> your
>> Gambas code like any other function and get and interpret its return
>> value.
>>
>> So, if this convention for error reporting is used, it is much
>> simpler to
>> get information about errors, without using Alloc() and co. Your library
>> may use a different convention which actually involves pointers, but
>> I wouldn't know.
>>
>> Regards,
>> Tobi
>>
> I should've said it in the beginning. Ofcourse any function returns
> integer value of 0 as success or -1 as error, but that only indicates
> that function was successfully executed or not. So GetStatus() will
> always return 0 because it shurely ran, nothing can go wrong here. But
> that's not the result I want. GetStatus() actually gives back a string
> with the status I asked for. Not that I fully understand how it does
> that. I already gave links to the libfptr.so library itself
> (http://allunix.ru/back/atol.tar.gz) and it's header files
> (http://allunix.ru/back/atol-header.tar.gz) so that it's clearer, what
> I'm talking about, unfortunately I am absolute zero in C to figure
> things out myself.
>
> For example I can see that to get serial number of the device driven
> by that library i can use a function described like this:
>
> get_SerialNumber(void *ptr, wchar_t *bfr, int bfrSize);
>
> As far as I can tell what it does is it gets data needed and puts it
> into some buffer. The result of executing this function through
> put_SerialNumber(kkmDrv) will always be returned to me as 0.
>
> So to see what's in that buffer, I have to then invoke
> GetStatus(kkmDrv) describe in .h file like GetStatus(void *ptr); and
> the integer result of this operation will also always be 0, which
> means that GetStatus itself ran successfully, but I don't care about
> that, I want to see what it actually told me, not that if it told me
> it successfully or not. So that's the main confusion. If all this is
> too complicated and lamely explained then nevermind, I expect it to be
> so and I'm sorry, that's the best I can do. I'm just really confused
> that I recieve two answers, one boolean telling if function
> successfully invoked and one string, carrying the actual data I want.
>
>
> Best Regards,
>
> Dmitry.
>
UPD: you know, I can be fundamentally wrong about all this library's
functionality. Maybe it does not give me any data afterall, I'm
beginning to think that this integer (or rather boolean) value is all it
gives me back, and the "real" data is just written into it's log file.
Which is sufficient to me, so, I guess, nevermind. Sorry about wasting
your time.

Best regards,

Dmitry.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

zxMarce
On 15/06/17 08:48, Admin wrote:

> 15.06.2017 17:54, Admin пишет:
>> 15.06.2017 16:19, Tobias Boege пишет:
>>>> All your help was very important for me, I now have completed my cash
>>>> register software to the point where it does everything my company
>>>> needs. I
>>>> must say Gambas is a great language, it's very easy to learn from
>>>> scratch,
>>>> I'm surprised how obvious everything is. But there is a lot of work
>>>> for me
>>>> left to do mostly in terms of managing wrong human actions. My
>>>> software
>>>> works good if the employee doesn't do any mistakes, but that's
>>>> unrealistic,
>>>> so there's a lot of things I want to control and check. And that's
>>>> where I'm
>>>> stuck.
>>>> This library (which still calls itself a driver) theoretically is
>>>> able to
>>>> return a lot of values that I need, but I can't understand basic
>>>> rules of
>>>> how do we take output from a C-lib in Gambas.
>>>> From http://gambaswiki.org/wiki/howto/extern I understood that I
>>>> need to
>>>> locate a space in memory and pass a pointer to a library so that it
>>>> can
>>>> write data into that place in ram, which I would then read and set
>>>> free.
>>>> So I have to declare a pointer, then Alloc(8) it, then pass it to
>>>> my library
>>>> and then read from it like it is a stream. Does this principle
>>>> still work in
>>>> current version of Gambas?
>>> If you do Alloc(8), then you get 8 bytes of memory. You most likely
>>> *don't*
>>> want to read that like a stream, but use Integer@() or similar
>>> functions.
>>>> What I don't understand is how I construct the code in my
>>>> particular case.
>>>> To make an interface to the library I declare external pointer like
>>>> this:
>>>>      Extern CreateFptrInterface(ver As Integer) As Pointer
>>>> Then I declare some pointers that I'll use with help of the
>>>> interface I
>>>> created:
>>>>      Extern put_DeviceEnable(p as Pointer, mode as Integer)
>>>>      Extern GetStatus(p as Pointer, StatRequest as String)
>>>> Then I declare the pointer which will be that interface:
>>>>      Public kkmDrv as Pointer
>>>> So then in sub I can do
>>>> kkmDrv = CreateFptrInterface(12) ' this establishes the interface
>>>> put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the
>>>> library
>>>> through the interface.
>>>> And it works great.
>>>> But then If I want to get some data from the library, as I
>>>> understand, I
>>>> have to declare another pointer, allocate ram for it and pass my
>>>> request.
>>>> I don't understand how should I pass that pointer to GetStatus()
>>>> while also
>>>> passing my interface pointer to it, let alone reading data back.
>>>> Totally
>>>> confused.
>>>>
>>> This entirely depends on how the C functions in your library are
>>> declared.
>>> I don't know about your specific library but commonly the occurence
>>> of an
>>> error is indicated by an integer return code, e.g. this might be the
>>> signature of one of the functions in your library:
>>>    int myfunction(void *interface, int argument)
>>> If the documentation says that the return value (int) of this function
>>> indicates an error, then you just need to get that return value back
>>> into
>>> your Gambas program, which you accomplish by declaring the function in
>>> Gambas as
>>>    Extern myfunction(interface As Pointer, argument As Integer) As
>>> Integer
>>> (notice the trailing "As Integer"). Then you can use "myfunction" in
>>> your
>>> Gambas code like any other function and get and interpret its return
>>> value.
>>> So, if this convention for error reporting is used, it is much
>>> simpler to
>>> get information about errors, without using Alloc() and co. Your
>>> library
>>> may use a different convention which actually involves pointers, but
>>> I wouldn't know.
>>> Regards,
>>> Tobi
>>>
>> I should've said it in the beginning. Ofcourse any function returns
>> integer value of 0 as success or -1 as error, but that only indicates
>> that function was successfully executed or not. So GetStatus() will
>> always return 0 because it shurely ran, nothing can go wrong here.
>> But that's not the result I want. GetStatus() actually gives back a
>> string with the status I asked for. Not that I fully understand how
>> it does that. I already gave links to the libfptr.so library itself
>> (http://allunix.ru/back/atol.tar.gz) and it's header files
>> (http://allunix.ru/back/atol-header.tar.gz) so that it's clearer,
>> what I'm talking about, unfortunately I am absolute zero in C to
>> figure things out myself.
>> For example I can see that to get serial number of the device driven
>> by that library i can use a function described like this:
>> get_SerialNumber(void *ptr, wchar_t *bfr, int bfrSize);
>> As far as I can tell what it does is it gets data needed and puts it
>> into some buffer. The result of executing this function through
>> put_SerialNumber(kkmDrv) will always be returned to me as 0.
>> So to see what's in that buffer, I have to then invoke
>> GetStatus(kkmDrv) describe in .h file like GetStatus(void *ptr); and
>> the integer result of this operation will also always be 0, which
>> means that GetStatus itself ran successfully, but I don't care about
>> that, I want to see what it actually told me, not that if it told me
>> it successfully or not. So that's the main confusion. If all this is
>> too complicated and lamely explained then nevermind, I expect it to
>> be so and I'm sorry, that's the best I can do. I'm just really
>> confused that I recieve two answers, one boolean telling if function
>> successfully invoked and one string, carrying the actual data I want.
>> Best Regards,
>> Dmitry.
> UPD: you know, I can be fundamentally wrong about all this library's
> functionality. Maybe it does not give me any data afterall, I'm
> beginning to think that this integer (or rather boolean) value is all
> it gives me back, and the "real" data is just written into it's log
> file. Which is sufficient to me, so, I guess, nevermind. Sorry about
> wasting your time.
> Best regards,
> Dmitry.
Dmitry,
With a desription such as get_SerialNumber(void *ptr, wchar_t *bfr, int
bfrSize); and having reviewed your communications, I would guess that:
  *ptr is a pointer to the interface (an input parameter),
  *buf is a pointer to a -possibly predefined- buffer that the function
will fill with data (the serial number in this case, could call this an
output parameter), and
  bfrSize can be sort of an input/output parameter. bfrSize can hold the
size in wchar_t units in input and the function may alter it to reflect
the actual string size returned in *buf.
All this is just guesswork of course, nothing solid; the actual proper
usage of the function should be not in the header files, but in the
documentation.
The way I would use this call is as follows:
1- Get an interface pointer, let's call it ptrItf. You know how.
2- Get an int or boolean for the function return value, let's call it
retVal.
3- Get a Gambas string filled with CHR(0), and a pointer to its data
(make the string big enough so that a serial number would fit, even in
non-ANSI strings such as UTF-8, and add some slack just to be sure),
let's call that pointer ptrBuf.
4- Get the lenght of the above buffer string, let's call that bufLen.
5- Call the function:
  retVal = get_SerialNumber(ptrItf, ptrBuf, bufLen - 1)
6- If retVal <> 0, increment (double) the string size and retry from 3.
Not in a forever-loop, just once.
7- If retVal = 0 then the serial number should somehow be in the string.
Maybe you have to convert between ANSI/UTF-8/etc., but it should be there.
Please note that the above is, again, guesswork. Not sure of anything.
HTH,
zxMarce.


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Working with .so library

Tobias Boege-2
In reply to this post by Admin
> > > > What I don't understand is how I construct the code in my
> > > > particular case.
> > > >
> > > > To make an interface to the library I declare external pointer
> > > > like this:
> > > >
> > > >      Extern CreateFptrInterface(ver As Integer) As Pointer
> > > >
> > > > Then I declare some pointers that I'll use with help of the interface I
> > > > created:
> > > >
> > > >      Extern put_DeviceEnable(p as Pointer, mode as Integer)
> > > >
> > > >      Extern GetStatus(p as Pointer, StatRequest as String)
> > > >
> > > > Then I declare the pointer which will be that interface:
> > > >
> > > >      Public kkmDrv as Pointer
> > > >
> > > > So then in sub I can do
> > > >
> > > > kkmDrv = CreateFptrInterface(12) ' this establishes the interface
> > > >
> > > > put_DeviceEnabled(kkmDrv, 1) ' this transfers the comand to the library
> > > > through the interface.
> > > >
> > > > And it works great.
> > > >
> > > > But then If I want to get some data from the library, as I
> > > > understand, I
> > > > have to declare another pointer, allocate ram for it and pass my
> > > > request.
> > > >
> > > > I don't understand how should I pass that pointer to GetStatus()
> > > > while also
> > > > passing my interface pointer to it, let alone reading data back.
> > > > Totally
> > > > confused.
> > > >
> > > This entirely depends on how the C functions in your library are
> > > declared.
> > > I don't know about your specific library but commonly the occurence
> > > of an
> > > error is indicated by an integer return code, e.g. this might be the
> > > signature of one of the functions in your library:
> > >
> > >    int myfunction(void *interface, int argument)
> > >
> > > If the documentation says that the return value (int) of this function
> > > indicates an error, then you just need to get that return value back
> > > into
> > > your Gambas program, which you accomplish by declaring the function in
> > > Gambas as
> > >
> > >    Extern myfunction(interface As Pointer, argument As Integer) As
> > > Integer
> > >
> > > (notice the trailing "As Integer"). Then you can use "myfunction" in
> > > your
> > > Gambas code like any other function and get and interpret its return
> > > value.
> > >
> > > So, if this convention for error reporting is used, it is much
> > > simpler to
> > > get information about errors, without using Alloc() and co. Your library
> > > may use a different convention which actually involves pointers, but
> > > I wouldn't know.
> > >
> > > Regards,
> > > Tobi
> > >
> > I should've said it in the beginning. Ofcourse any function returns
> > integer value of 0 as success or -1 as error, but that only indicates
> > that function was successfully executed or not. So GetStatus() will
> > always return 0 because it shurely ran, nothing can go wrong here. But
> > that's not the result I want. GetStatus() actually gives back a string
> > with the status I asked for. Not that I fully understand how it does
> > that. I already gave links to the libfptr.so library itself
> > (http://allunix.ru/back/atol.tar.gz) and it's header files
> > (http://allunix.ru/back/atol-header.tar.gz) so that it's clearer, what
> > I'm talking about, unfortunately I am absolute zero in C to figure
> > things out myself.
> >
> > For example I can see that to get serial number of the device driven by
> > that library i can use a function described like this:
> >
> > get_SerialNumber(void *ptr, wchar_t *bfr, int bfrSize);
> >
> > As far as I can tell what it does is it gets data needed and puts it
> > into some buffer. The result of executing this function through
> > put_SerialNumber(kkmDrv) will always be returned to me as 0.
> >
> > So to see what's in that buffer, I have to then invoke GetStatus(kkmDrv)
> > describe in .h file like GetStatus(void *ptr); and the integer result of
> > this operation will also always be 0, which means that GetStatus itself
> > ran successfully, but I don't care about that, I want to see what it
> > actually told me, not that if it told me it successfully or not. So
> > that's the main confusion. If all this is too complicated and lamely
> > explained then nevermind, I expect it to be so and I'm sorry, that's the
> > best I can do. I'm just really confused that I recieve two answers, one
> > boolean telling if function successfully invoked and one string,
> > carrying the actual data I want.
> >
> >
> > Best Regards,
> >
> > Dmitry.
> >
> UPD: you know, I can be fundamentally wrong about all this library's
> functionality. Maybe it does not give me any data afterall, I'm beginning to
> think that this integer (or rather boolean) value is all it gives me back,
> and the "real" data is just written into it's log file. Which is sufficient
> to me, so, I guess, nevermind. Sorry about wasting your time.
>

Don't worry about wasting my time. If I didn't want to use it, I wouldn't
have looked at your mail.

Let's have a look at fptrexample.cpp in atol-header.tar.gz which was linked
somewhere in this thread, e.g. these two instances where the programmer gets
data back from the library:

   54     int rc = EC_OK;
   55     iface->get_ResultCode(&rc);
----------------------------------------------------------------------------
   59         QVector<wchar_t> v(256);
   60         int size = iface->get_ResultDescription(&v[0], v.size());
   61         if (size <= 0)
   62             throw Exception("get_ResultDescription error");
   63         if (size > v.size())
   64         {
   65             v.clear();
   66             v.resize(size + 1);
   67             iface->get_ResultDescription(&v[0], v.size());
   68         }
   69         resultDescription = QString::fromWCharArray(&v[0]);

It's a little hard for me to transfer these into Gambas because I don't use
the Extern functionality in Gambas very often and I don't have the library
or the hardware to test my code -- but if you can accept a margin of error,
let me try.

What you have to do is look at how the C++ code uses the method of the
interface object. (BTW, I strongly suggest you get acquainted with C/C++!)
Gambas can't use the C++ interface, but luckily the library has a sane
C interface, too, so you have to look into the ifptr_c.h header to find
something that looks just like the get_ResultCode() method of the interface
object. This one looks very promising (as it has the same name):

   29 DTOSHARED_EXPORT int DTOSHARED_CCA get_ResultCode(void *ptr, int *resultCode);

Its signature tells you that you have to pass as the first argument ptr
(probably) your interface pointer (this makes a lot of sense, of course).
The second parameter is a pointer to an integer. This is where the
get_ResultCode function will store the result code (whatever that means).
You can also see that the return value of the function is int. The return
value from the function indicates if the get_ResultCode() call was
successful or not and if it was successful you will find the result code
you wanted written into the resultCode pointer that you passed. This
function signature translates to:

  Extern get_ResultCode(ptr As Pointer, resultCode As Pointer) As Integer

Assuming you already have a valid interface pointer ifptr you have to
call this function like this:

  ' Initialise the variable with EC_OK, as in line 54 above (the
  ' atol-header.tar.gz does not contain a definition of that thing,
  ' so you have to find it somewhere else):
  Dim iCode As Integer = ???

  get_ResultCode(ifptr, VarPtr(iCode))

Look up what VarPtr() does in the Gambas documentation. You can then just
use the iCode variable in your Gambas program. It contains the result code
you wanted to query from the library.

Now the second part (lines 59--69) are a little more difficult, because
you have to give a string buffer to presumably receive some description
of something. Again find the C function corresponding to the C++ method:

   30 DTOSHARED_EXPORT int DTOSHARED_CCA get_ResultDescription(void *ptr, wchar_t *bfr, int bfrSize);

It expects an interface pointer, a buffer of wchat_t's and the size of
that buffer (probably measured in wchar_t units and not in bytes).
Now, Gambas doesn't have a datatype corresponding to wchar_t and, sadly,
the size of a wchar_t is not standardised. You have to find out how big
a wchar_t is on your system or assume it's less than 8 bytes or work around
this issue some other way. I'll assume in the following that a wchar_t
consists of 4 bytes, because that is how it is on my system. So you
allocate a buffer that is enough to hold the description. The person who
wrote the C++ code thought that 256 characters might be sufficient:

  Extern get_ResultDescription(ptr As Pointer, bfr As Pointer, bfrSize As Integer) As Integer

  ' Note that you should not do what zxMarce hinted at and get a Gambas
  ' string and use VarPtr on it to get a string buffer, because, as the
  ' VarPtr documentation tells you, Gambas strings are read-only. You
  ' should not pass a VarPtr to its contents to an external function that
  ' may modify the contents. (Although it would probably be okay in this
  ' case, but the reason lies in how Gambas manages strings internally,
  ' but this is getting too far.)
  Dim pBuf As Pointer
  Dim iSize As Integer

  ' Create and clear the buffer. 256 characters and each character is 4 bytes.
  pBuf = Alloc(String$(256 * 4, "\0"))
  iSize = get_ResultDescription(ifptr, pBuf, 256)

Now just imitate what the C++ programmer did -- some error checking:

  If iSize <= 0 Then Error.Raise(("get_ResultDescription error"))
  If iSize > 256 Then ' the library needs more space than you provided
    ' Make the buffer larger and try again.
    ' I don't think the C++ makes much sense because it only increases
    ' the buffer length by 1 and tries again. There isn't even a loop.
    ' Anyway, figure this out yourself.
  Endif

Finally we want a real Gambas string out of the buffer pBuf. The C++
programmer kind of has the same problem in line 69. He doesn't like
wchar_t either and converts it to a QString. Get the string in pBuf
as a Gambas string by using String@() and then convert it from wchar_t
format to UTF-8. Then it's ready to be used in your program.

  Dim sDesc As String

  sDesc = Conv$(String@(pBuf), "WCHAR_T", "UTF-8")
  ' The documentation of String@() tells you not to Free() the pBuf you
  ' created the string from, until you are done dealing with the string.
  ' I _guess_ that since we Conv$'d the string, we can now Free the
  ' original pBuf, but you have to verify this!
  Free(pBuf)

I hope this gets you started. You should really look into C/C++ though.

Regards,
Tobi

--
"There's an old saying: Don't change anything... ever!" -- Mr. Monk

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gambas-user
Loading...