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 Gambas-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gambas-user