|
Post by alexander on Jan 13, 2016 13:04:51 GMT 1
Hi....
I started years ago with my ATARI with GFA BASIC... I changed to Windows 16BIT Version, later to 32 BIT Version... and I really use a lot - for everything... But all the time - I have Problems with using DLLs or OLE objects.... most because of teh var types.
At this time I like to use a library from REALAND. This is the "cheap Chinese stuff" leader for Access control systems or "work time counter".... I got the SDK:
www.realandbio.hk/download/sdk/RL10079DesktopDemo_20151021.rar They have examples in C++, VB and DELPHI... I installed the OLE correct - all Demos are running and my GFA "first step" show also a positive result.
So I can call the OLE. I can connect.
But I can not use "GetProperty" and "SetProperty"... I allways receive error - like "Variant?" - "The given OLE-Variant is..."
I do not understand how to decalre the right vars, which I have to use to catch the results...
In DELPHI they use a SAFEARRAY - In VB the use a function from the OLE to generate vars.... but here - I also receive Errors...
Dim DEV As Object Dim DEVC As Object Dim DEVT As Object Dim DEVE As Object Dim DEVP As Object
Set DEV = CreateObject("Riss.Devices.Device") Set DEVC = CreateObject("Riss.Devices.Zd2911DeviceConnection") Set DEVT = CreateObject("Riss.Devices.Zd2911Tools") Set DEVE = CreateObject("Riss.Devices.Enroll")
DEV.DN = 1 DEV.Model = "ZDC2911" DEV.IpAddress = "192.168.2.180" DEV.IpPort = 5055 DEV.CommunicationType = 1 DEV.Password = "0" DEV.ConnectionModel = 5
Print DEV.CommunicationType Print DEVC.Open(DEV)
Dim extraProperty(4) As Byte Dim extraData(4) As Byte Dim ib As Byte, i as int Dim res as Variant
ib = 0 For i = 0 To 15 extraProperty(i) = ib extraData(i) = ib Next i
res = DEVC.GetPropertyExt_2($00000010, V:extraData(0), DEV, V:extraData(0))
I guess the Problem is, because no one has such a device at home - their is not much help... ;-((((((
But maybe, someone has some more examples with OLE and how to generate var types...
I like to build some free tools.
Alexander
|
|
|
Post by dragonjim on Jan 13, 2016 23:20:39 GMT 1
Hi Alexander,
GB32 can be temperamental with Objects at times (and there are a very few objects which it can not handle); however, most of the time, a bit of trial and error (and lots of perseverance!) works wonders.
Rather than go on a rant about Objects which may or may not be helpful, it might be useful to start with to let me know what happens when you run the example code you gave in your post, and we can go from there...
For examples on OLE Automation, look at the page 'Automation' in the new English CHM Help file.
|
|
|
Post by alexander on Jan 14, 2016 10:49:01 GMT 1
Hello,
Thanks for reply. You are absolutely right - testing and trying - step by step - will bring the best results - sometimes - after hours.... ;-) And I know about the possibilities with GFA. I have several tools for image manipulation based on CSXImage OLE - I handle large images with about 60MP. I have several GPS tools working with COM port use and some biometric scanners for fingerprints, RFID cards and chip cards... everything worked after a while of testing... ;-)
This time it seems a little bit more difficult. If I have a look to the samples - it seems they use a Tools/Utility function to generate different data types or place holders. My problem is, that I already fail with this.
If I try:
Print DEVT.GetBytesByNum("4", $00000003)
I receive "Variant type?"
If I declare a as Variant and use
a = DEVT.GetBytesByNum("4", $00000003)
it shows no error but I don't know how to handle "a".
If I read the samples - I think a must be the type of var, which I need to work with GetProperty or SetProperty.
If I use
result = DEVC.GetPropertyExt_2($00000010, "", DEV, V:a)
...where result is a Boolean and DEV is the DEVICE.... I allways receive "Error 0x80070057 Die angegebene OLE-Variante ist ungültig". And I tried any combination - without "V:" - without any var...... ;-(((
Alexander
|
|
|
Post by dragonjim on Jan 14, 2016 12:18:29 GMT 1
Hi,
Just a quick question: after the...
a = DEVT.GetBytesByNum("4", $00000003)
...line, use either (or both):
Print VarType(a) Print TypeName(a)
What are the results?
|
|
|
Post by alexander on Jan 14, 2016 13:09:34 GMT 1
it is Byte()
This is an Bytearray - right? But I think this is okay than.
This is the VB example:
Dim extraProperty() As Byte, extraData() As Byte Dim result As Boolean ReDim Preserve extraData(0) As Byte ReDim Preserve extraData(1) As Byte ReDim Preserve extraData(2) As Byte ReDim Preserve extraData(3) As Byte extraData = deviceTool.GetBytesByNum(CStr(DeviceSerialNo), NumberType_Int32Bit) result = deviceConn.GetPropertyExt_2(DeviceProperty_SerialNo, extraProperty, d, extraData)
Where... DeviceSerialNo = 67 as long NumberType_Int32Bit= $00000003 DeviceProperty_SerialNo=$00000010
I always receive the same error - "Error 0x80070057 Die angegebene OLE-Variante ist ungültig".
|
|
|
Post by alexander on Jan 14, 2016 13:14:03 GMT 1
If I compare the given error to other script languages - it means "OLE - parameter error"
|
|
|
Post by dragonjim on Jan 14, 2016 18:19:59 GMT 1
As an aside, a more direct translation could be closer to "The specified OLE variant is invalid", which may or may not be important.
My confusion is: in the VB Example, there does not appear to be a Variant. There are two dynamic arrays, one Redim-ed to contain four elements (extraData) and the other left empty (extraProperty), and a boolean variable (result).
Then the program tries to insert a 32-bit integer value into extraData (I am assuming that each byte is allocated to each element - to the best of my knowledge, this is not possible in GB32, but could replicated to returning the value to a different 32-bit integer and transferring it to the array using the GetByte0 family of functions - however, I would just replace the extraData array with an Int32 variable and use that in the last line instead, as this should give the same result as was intended).
Finally, the program is asked to return additional properties into the empty array extraProperty (is this what is happening?), specifying an unknown and undeclared parameter 'd', with the success or failure being returned to the result variable(?). Have I understood this correctly?
If so, then there are a few areas where there will be problems, but the Variant error may be caused by either the abovementioned problem with populating 'extraData', 'extraProperty' being undefined or 'd' being undeclared.
Does any of this help?
|
|
|
Post by alexander on Jan 14, 2016 22:50:13 GMT 1
Thanks for your help - but I think it's time to stop here. I spend to much hours with this. The SDK - I posted the link above - includes VB, DELPHI and C++ source code. I checked DELPHI and VB, it works... so the first time ;-((( I have to change to DELPHI...
I guess the problem is somewhere else - or I'm really to stupid - to make it...
The VB code:
extraData = deviceTool.GetBytesByNum(CStr(DeviceSerialNo), NumberType_Int32Bit)
returns just a ByteArray. I compared with C++ and DELPH - in C++ they don't use the OLE function in "deviceTool" - they just make it with by "their own"...
This ByteArray is inserted in "extraData"...
I understand - that they prepare "extraData" to the right size and type - to receive the result!
In VB they use: txt_FV.Text = deviceTool.GetString(extraData) later to show - in this case - the firmware version
"extraProperty" is used to send more data to the device - for example to select an user by id - and receive in a complex object "extraData" als user date (User.Id, User.Name, User.FingerprintData,......)
This is how they explain the function:
public abstract bool GetPropertyExt_2(DeviceProperty property, object extraProperty,ref Device device, ref object extraData)
Parameter: property = settable device property; extraProperty ? settable extended property; device = Device entity; extraData= extra information
;-(((
|
|
|
Post by dragonjim on Jan 15, 2016 1:32:17 GMT 1
Sorry I couldn't help further, but without experience of the library and in how it works it's not easy - and as you say, there are time restraints for all of us . Good luck with Delphi and I hope you make it work.
|
|
|
Post by alexander on Jan 15, 2016 12:12:03 GMT 1
Hi again....
In DELPHI it worked from the beginning - but I don't like it.
Just for me - and if you have a bit time:
DELPHI uses an "Object"
How do I create an empty object (not Nothing) and how will I place it in the function call?
VB uses a "ByteArray"
Is there a ByteArray - how can I make place it in the function call?
C++ uses "PSafeArray"
Is there something compatible in GFA...and same questions like above....
Maybe this will help me in the future.
THANKS A LOT!
|
|
|
Post by dragonjim on Jan 15, 2016 15:58:14 GMT 1
You can create an empty Object but you must first define the structure the object takes:
a. if you know this, you can create a Type, create a variable of that Type (but do not populate it), and pass the pointer (or V:) of this variable as an Object pointer b. if you don't know the structure but you do know the size of the object, then an adaption of VB's ByteArray could be used (in your previous example, the size was four) using a similar Type object made up exclusively of Byte-sized elements (in your example, there would be four of them). c. if you don't know an Object's structure or size, then you can either set up a Type as in (b) with, let's say, 100 elements (i.e. Type ByteArray : - Byte ele(100) : EndType) - or more if this still isn't big enough - and, as long as the functions you are working with expect a pointer to an Object rather than the object themselves, this should still work. An example of this is the CRITICAL_SECTION option used in multi-tasking: originally, this was defined as two Int32 Dummy values (the object itself is extremely complicated and multi-faceted - the Type created purely forms a reference for the main object which the API function creates); however, somewhere along the line, at least one or two extra Int32 elements have been added, so, to be on the safe side, I always create a Type with at least five Int32 Dummy values and this works fine - it may not use them all (I have yet to see a change in the fifth value) but it still works as expected.
To answer you other questions:
ByteArray - a ByteArray, as I understand it, is simply an array of bytes used when object types are not known, but their sizes are.
PSafeArray - a Borland implementation of Microsoft's SafeArray, which itself is a simple Variant array, which is used in multithreading applications and can be locked when being used by one thread so as not to cause a conflict/error if another thread tries to use it at the same time. Generally, all non-dynamic global arrays in GB32 are thread-safe, except for un-fixed Strings and undefined Variants which can cause a problem.
|
|
|
Post by alexander on Jan 15, 2016 22:02:25 GMT 1
SO: Guess what? ;-) You remember: extraP=DEVT.GetBytesByNum(CStr("1"), $00000003) extraD=DEVT.GetBytesByNum(CStr("1"), $00000003) res = DEVC.SetPropertyExt_2(16, extraP, DEV, extraD) First two lines are to generate the vars. extraP is additional property data and extraD is to receive data. I tried hours - always the error I already posted. I declared extraP as variant, same with extraD. After this function I checked with TypeName - the result was Byte() If I use the vars in the third line - I receive the error. I tried to build my own Byte() - error. NOW: I just put line 1 and 2 in line 3: res = DEVC.SetPropertyExt_2(16, DEVT.GetBytesByNum(CStr("0"), $00000003), DEV, DEVT.GetBytesByNum(CStr("0"), $00000003)) AND - IT WORKS FINE !!! For the moment I'm happy. So - the only problem I have - I'm not able to build the right var to store line 1 and line 2 and use it in line 3. I need to - because - this first try - just sends a value to the device - there is no response I have to take care about. All other functions I need - are together with a response, which will be stored in extraD. So in this case my nice solution will not work. Maybe my problem is building just the ByteArray: I tried: Dim b() as Byte But how can I insert the results of the function (line 1 or line 2) into b I tried: Dim b(4) as Byte and set all b(x) to 0 in line 3 I used V:b(0) to point to b - is this correct? My problem must be so close.... ;-(
|
|
|
Post by dragonjim on Jan 16, 2016 0:27:56 GMT 1
Not got much time tonight but the last bit should work if the object is only four bytes long. (In fact you only need Dim b(3) if your Option Base is 0).
If that doesn't work, try declaring extraData as an Int32.
|
|
|
Post by alexander on Jan 17, 2016 11:48:56 GMT 1
Now - maybe a most simple question:
---------
I declare A as a Variant I use the OLE-Function to generate a "Result VAR" Now the Variant A is of Type Byte()
I use A direct in the OLE Function to control my device and it works
-------------
I declare A() as Byte I fill A(0),A(1),A(2),A(3) like in the result from the function above Isn't a now Byte() ?
1) How do I give A to the function now?
I tried V: or just A(0) - nothing works?
2) Is it possible to change a VARIANT to BYTE()
Thanks for all the patience ...
|
|
|
Post by dragonjim on Jan 17, 2016 21:47:20 GMT 1
Hi,
I think the problem we're both having here is with the term Byte Array, in that we are assuming that it is an array of bytes. Actually, it appears that a ByteArray() or Byte() is actually a data type in itself, which is where you may be running into problems with GFABasic, because it doesn't have such a data type. Just to be sure, can you tell me the result of VarType(A) where A is your variant?
Thanks.
In the meantime, I shall ask some questions...
|
|
|
Post by alexander on Jan 17, 2016 23:09:20 GMT 1
VarType = 8209
8192 + 17 / Array + Byte
-----------
Is there a way to give an Array - like A - to the function - without V: ?
|
|
|
Post by dragonjim on Jan 17, 2016 23:41:15 GMT 1
So it is a Byte Array in a Variant...I can get a variant array into a variant by not a byte...you can do it in C++ and even VB6 but not in GB32.
The only answer I can give to your question is: No, I do not think so, as it looks like it must be a byte array.
As I said before, I am going to ask around about this and get back to you.
|
|
|
Post by dragonjim on Jan 19, 2016 1:24:04 GMT 1
Had a word and I need some more information from your end.
Could you let me know the typelib declaration of the SetPropertyExt2 function, please. Also, is there a C++ example for this example?
Thanks.
Oh, and to give you a proper answer as to whether you need to use the V: command: generally, when passing arrays/strings/variants to functions, the function requires a pointer to the array/variable, so it is advisable to use V: - that said, I've known instances where it actually breaks the functions, but that is usually with pre-defined Windows APIs.
|
|
|
Post by alexander on Jan 20, 2016 21:24:17 GMT 1
Hi - thanks for you response. Mh...I thought that .... I compared my DMX functions (another OLE I use) to this one.... My DMX function uses also a ByteArray - I also point with V: to Data(0) and it works.... Here it's different.... It seems - the function does not accept something with V: .... It is also a bit confusing - that the value - you give to the function with special data inside - is also used to give a result from the function..... In my first post I posted the link: www.realandbio.hk/download/sdk/RL10079DesktopDemo_20151021.rarHere is the complete source code - VB, DELPHI, C++ , ect.... May you will have a look.....
|
|
|
Post by dragonjim on Jan 21, 2016 17:46:07 GMT 1
Hi,
An answer to your query about SafeArrays and ByteArrays in GB32:
SafeArrays are created by using the = Array() function, so the following will create a SafeArray in a Variant of type Variant:
Dim A As Variant A = Array(3, 4, 5, 6)
To make the SafeArray of type Byte (or a ByteArray), use the 'As Byte' after the = Array() function as follows:
Dim A As Variant A = Array(3, 4, 5, 6) As Byte
Any array created using this method should be compatible with any of the functions that you are using with your OLE library (many of which require a ByteArray, noted as Byte[] in their declarations); whether they should be passed as the Variant containing the array (without V:) or as a pointer to the Variant (with V:) is down to how the functions were written, but I would guess that the latter case is more likely to be true; in very odd instances, it may require the use of the 'Pointer' command/function (see the help file), although I would be surprised if this was the case.
I hope this proves helpful.
|
|
|
Post by scalion on Apr 12, 2018 8:39:25 GMT 1
Hi, After looking the vb example : ReDim Preserve extraData(0) As Byte ReDim Preserve extraData(1) As Byte ReDim Preserve extraData(2) As Byte ReDim Preserve extraData(3) As Byte extraData = deviceTool.GetBytesByNum(CStr(DeviceSerialNo), NumberType_Int32Bit) Maybe you can try this : Type Type_ExtraData -Byte a(4) EndType Global a As Type_ExtraData a = DEVT.GetBytesByNum("4", $00000003) // Or CStr("4")...
Or a as long (it's 4 byte too)
Good luck
|
|
|
Post by scalion on May 4, 2018 15:28:25 GMT 1
Ok now i think your problem is : you must use IsNull() (or IsNothing for object) Statement before assing value to your variable. But i can't test on your program.
Try Change this : a = DEVT.GetBytesByNum("4", $00000003)
By this : If Not IsNull(DEVT.GetBytesByNum("4", $00000003)) a = DEVT.GetBytesByNum("4", $00000003) Else // here your code to set with zero value for example ... a = 0 Endif
|
|