Hello Lou,
-- Ok...try this. This binds to libusb-1.0.20. You can get the binaries here: http://libusb.info/ (Downloads -> Latest Windows Binaries). The header file is fully wrapped and you can run KscLibUsbApp examplePrintBasicDeviceAttributes to try out basic functionality. All functions from the libusb.h header file just need to be referenced from the appropriate OSObjects or Application-level object. For example, libusb_free_bos_descriptor() should be called from KscLibUsbBosDescriptor>>free. We also need to hookup the callbacks -> EsEntryPoints so we can get notification during actions like transfer and when someone plugs/unplugs a usb device. Most of these structs are pretty low-level concepts...therefore..I would suggest some set of simple interface classes which wrap/delegate to 1..n of these structs. For example, I could see there would be a UsbDevice object and a UsbTransfer object. I would either put those in a separate application or have the top-level app be the interfaces and create a subapp to hold the OSObjects. Those are some ideas for you. Your context thoughts sound right...it may be easier if you are going to do a simple set of interface classes, just to have that managed there rather than in the OSObjects. You may want to consider moving this up to Vast Goodies to facilitate exchanges? -- Seth On Saturday, February 6, 2016 at 2:18:09 PM UTC-5, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. KscLibUsbUpdate1.dat (375K) Download Attachment |
Hi Seth,
I'm using the DLL from the MS32 folder. As for the structures I was building, I may have started with other .h files and jumped around the Internet looking for definitions, so I may well have a hodgepodge. Hopefully what you have done replaces the mess.
Make sense.
Great idea.
Okay, I will think about that once I'm up on v8.6.2 and I catch up to you.
Good.
Okay, I expect you are correct, just want to think about it once I cann see the big picture.
Will do. Lou
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Lou,
-- Got it. Yes, I just made everything conform to the public header file 'libusb.h'. That should be the only one we need to deal with (pending some very specialized use case). The enums and #defines are in the LibUsbConstants pool dictionary. The functions marked LIBUSB_CALL are the exportable ones that are in LibUsbFunctions I removed the functions marked 'static inline' in the header from LibUsbFunctions...because those are not exportable. If need be, they can be rewritten in Smalltalk if they are useful. The KscLibUsbApp>>examplePrintBasicDeviceAttributes test works on the 64-bit vm/image...so that looks good. This should also work on Linux. I included a small update attachment because there were some old pool variable references still in there. -- Seth On Monday, February 8, 2016 at 9:54:18 AM UTC-5, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. KscLibUsbUpdate2.dat (387K) Download Attachment |
Hello Seth, I'm updated to v8.6.2. I imported your latest version. It looks great!! Although I haven't tested it much I think we have a functional API. I made the change to usbContext and added initDefaultContext and initNewContext and uploaded the new version to VAST Goodies. I think it is a good time to do some clean up work. I put some comments in the #initializeAfterLoad methods of the structures that are probably not needed with the new members:types: way of defining them. Unless you have an objection, I think I will remove them. I also started adding getter and setter methods to the structures. I'm not sure if they are all needed, especially the setters. Did your magic structure generation take care of all these? You probably noticed the KscLibUsbApp class variables "UsbContext UsbDevicePointers UsbDeviceDescriptors ". The idea behind them was to hold on to the context, pointers (from LibUsbGetDeviceList) and descriptors (from LibUsbGetDeviceDescriptor) respectively. I'm not married to this idea, so I would like to know what you think. I have done nothing to free the structures, so if we keep these, something should be added to free things when they are no longer needed. You mentioned:
I expect I agree but I'm not sure what these classes would do. Maybe I will understand better after I play around a bit. If you have anything in mind, I would love to here it. Are you on Skype? You can SkypeMe at: callto://PhotonDemon (I'm not sure the callTo: will work). Talking via Skype may be easier than all this typing. Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Administrator
|
>> Talking via Skype may be easier than all this typing.
-- That's true. But, I am surely not the only one who is interested in how this progresses. Please post updates. :-) On Monday, February 8, 2016 at 3:22:03 PM UTC-8, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Richard, I'm glad you are interested in this project and will certainly post updates. A version is on VAST Goodies. It requires VA Smalltalk v8.6.2 because we use features of OSStructure that make them easier to define and work on 32 and 64 bit platforms. It has OSStructures for all the LibUSB structures. It has Pragmas that define most relevant constants and almost (if not all) the LibUSB functions. There is one example (thanks to Seth) and I'm working on another. It binds to libusb-1.0.20. You can get the binaries here: http://libusb.info/ (Downloads -> Latest Windows Binaries). I'm using the DLL from the MS32 folder. I'm working on 64 bit windows 10 home. Seth has tested with the new up coming 64 VA Smalltalk VM. Our interface should work on Linux with the proper Linux version of LibUSB. For now you need to know a lot C to use the interface. As time permits we will add more Smalltalk to make it easier. I intend to upload a new version late Thursday or early Friday. Lou
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Administrator
|
On Wednesday, February 10, 2016 at 6:41:19 AM UTC-8, Louis LaBrunda wrote:
--
I'm less interested in USB, per se, than I am in the process you are working through. So, I am quite interested in the problems you encounter and their resolutions. But, do keep us apprised of your progress, too!
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Richard,
-- Seth is better equipped to describe the process than I am. I will give a quick outline, sorry if it is too simplistic. These interfaces are usually to DLLs or in Linux SOs. They are almost always written in C. As such they have one or more ".h" files that describe the constants, structures and functions of the system. The task is to map these to Smalltalk. VA Smalltalk constants can be given reasonable names and defined in Pragmas. Functions can also be given reasonable names and defined as PlarformFunctions in Pragmas. The PlarformFunction definition links to the DLL and the name of the function in it and lists and describes the parameters (their C type). I can usually manage this from the .h file but a real C guy shouldn't have a problem. Then there are the structures, they are usually sub-classes of OSStructure. In v8.5.2 defining these is a little easier than it was before. In older versions you declared the field names (members) and in the setter and getter methods hand coded the offset to the data. In the new version you declare both the field names and their C type. This allows setters and getters to reference the member name and it calculates the offset from the C type list. You still need to define how to convert the data to a Smalltalk instance like:
This is where I run into trouble with things like pointers to pointers and three levels of indirection and such. If you know both Smalltalk and C, this probably isn't too bad (but it is harder than defining the functions). It is why I am very grateful for Seth's help (I think he wants to use this with a USB game controller and I want to talk to an X10 home controller). With both the members and there C types defined, I'm not sure why this:
and have the #at:put: figure out how to convert the value from the defined member name as C type. That would make defining the setters and getters even easier and could be automated. Seth may have and answer. Lou
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hello All, Lou...this was a great overview of the process. I hope people find their way here if they are wondering how to get started with developing bindings to C libraries with VA Smalltalk (...and I'm saying this verbosely since this will be google indexed:) Making member access to OSObjects even easier...(i.e. getters/setters) Lou is right...this can be even easier. In fact, it can be reduced even to the point where you don't need explicit setters/getters. Imagine a special subclass called OSReflectiveStructure that has a doesNotUnderstand: handler on it. It can look at the message and determine if this is a member getter or setter. If not, then pass it along...if so, then do all the work to figure out what to return. The reason that this was not done in 8.6.2 comes in 3 parts. Performance, Type Ambiguity...and the easy one...8.6.2 Delivery Time:) Performance: OSObjects are a performance critical part of the product. They have vm assistance...and the vm has direct knowledge and assumptions about the shape of an OSObject. For example, the reference and offsetAndRefType fields...the vm knows exactly where to find those. It also has a lot of vm assisted primitives for quick access to memory. When accessing memory....we want to get it to a primitive call as quickly as possible. More indirection via message sends to get to this point simply boils down to more instructions that must be executed. In regards to my task of updating every framework we have for 64-bit compatibility, I wanted to be cautious about how much indirection I introduced. I could tell how much additional time getters/setters via Symbols vs Integers were taking via microbenchmarks...but I could not get a good measure, ahead of time, of what impact this would have had if this additional cost was amortized across the product. And since providing these nicer types of getters and setters did nothing but add runtime to the existing parts of the product....I chose to keep the getters/setters as is, but change the hard-coded offset for a symbol instead of a very generic access like 'self memberAt: #field'. I always had plans, and still do, to introduce this. This is the main reason why I keep the type information around. Currently, it doesn't really need it after it computes the offsets...but we would need it for these nicer APIs. For certain bindings, where most all the work is done in C, the additional cost of member access would be a non-issue...so it would be best to start with these...and if you find the cost of certain accesses are heavy...then you can selectively fall-back to the lower level APIs. That will be the plan. Type Ambiguity: When updating the product, I noticed that existing getters/setters were not uniform in the way they wanted to represent certain field types. For something like a char *, that would end up being a null-terminated string, may be returned by some getters as an OSChar8, others may have returned an OSStringZ....and others may have returned just a generic OSPtr...and so on. This meant that in my automated tooling to update the getters/setters, I could not easily tell what should be returned. Something like a membersAt: API would need to make a decision to return this as probably an OSStringZ....however....if I did this for the existing ones...this may have changed the expectations of senders of these accessors and break the product in ways that would be hard to find. So this was not done...and as I said...for existing bindings this has very little advantage. 8.6.2 Delivery Time: This one is easy...I ran out of time. -- Seth
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Administrator
|
Thanks, both of you, for the detailed write ups.
-- On Thursday, February 11, 2016 at 12:13:31 PM UTC-8, Seth Berman wrote:
It was excellent! I am somewhat familiar with the process of interfacing to a library. I was looking for what you learn as you go through the process, the little details, the "gotchas", etc. :-) One of these days, I will have to write up the work I did to make VA support the C function call style of VW. (A subset, actually. Just what was needed to be able to use the VisualWorks code for GBS to interface to the GCI DLL.)
I hope you don't. Performance aside, there are the issues of clarity, discoverability, and verifiability. With explicit methods, you can find the implementors of sent messages. That also affects Scintilla's highlighting, although you can probably "guess around" that. Being able to connect the dots is important, so being able to find the actual method doing the work helps. And seeing what the method does helps verify that everything is correct. Generated accessors with offsets in class variables or something like that works better for me.
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Richard,
-- Your probably right...just pointing out all the information is there to make that happen. There could just as easily be some mechanism to invoke a "Generate Member Accessors" that effectively provides the same ease of development while making it explicit. Sure glad I didn't add it:) Always good to hear feedback...thanks! -- Seth On Thursday, February 11, 2016 at 5:42:20 PM UTC-5, Richard Sargent wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Louis LaBrunda
Hi Everyone, To answer my original question, there is no bug in OSPtr, OSStructure or any of their relatives (at least none that I know of) it was just my lack of C knowledge. Seth or I will start a new thread soon to describe our experience with building and using the interface to LibUSB. We will continue to post to this thread about the more general topic of building a VA Smalltalk interface to a DLL. To that point, we have added instance variables to one of our sub classes of OSStructure. When you think about it, it is a perfectly normal Smalltalk thing to do but not necessarily obviously given the objects map OS/C structures. Seth has even added a Class variable to one. Again, perfectly normal, just saying no reason not to, if it makes sense for your interface. We also added methods beyond the setters/getters so that users of the interface (like me) don't have to know/remember as much C to go to and from Smalltalk objects to the structures. Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Administrator
|
On Wednesday, February 17, 2016 at 6:48:54 AM UTC-8, Louis LaBrunda wrote:
--
Thanks, Lou. This is the kind of information I was looking for. Will you provide details about what purpose the extra variables have and how the extra methods help? (I realize this is very specific to the USB project, but I think the information in context will be good to know.) You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Richard,
We will. I will start the LibUSB post soon with information about what and how the instance variables are used. We will try to post USB specific information to the new thread and will continue to post to this thread that are of a more general nature. Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Richard Sargent
Hi All,
-- I guess I can speak to some of these decisions. Lou is going to start a new thread with LibUSB development which will probably have a lot of information about this. I'll talk now about it as if I were the expert...but really a lot of these organizational decisions with native bindings concerning how the code is organized (i.e. where put additional state, interfaces and so on) come down to best-practices and patterns. I find every time I do a native binding my view of these changes a bit...so I'm a work in progress. But today, based on what I know/learned, I would say the following: I'll first start with what basic pattern we ended up following to implement LibUSB which is the 1-Layer Pattern (Rich OSObject pattern...whatever you want to call it). I'm sure there are more (thoughts welcome), but there are at least 2 basic patterns that can be followed when wrapping a native library in VA. 1-Layer Pattern: In this pattern we seek to work with just the OSObjects. This means it is the OSObjects, themselves, that provide binding information on one side, and on the other side a rich high-level API which the user will work with. Product Example: OpenSSL Cryptography bindings use this pattern. Tradoffs: - Can be good to use if the native project to which you are binding exposes a cross platform API (meaning you don't need multiple versions of OSObjects for each platform). - Can be bad to use if you feel you are going to need multiple independent bindings that should all conform to a common interface. (An example is database drivers). - Even with high-level APIs available...at some point you may want to provide a more smalltalk idiomatic way to work with them. For example, if some behavior could be expressed as a Stream..but there isn't any OSObject equivalent exposed...then you begin to move towards a 2-layer approach, where you create smalltalk stream objects that manage/talk to the OSObjects....and you just deal with the streams. - There is no reason you couldn't start with 1-layer and then move to a 2-layer approach (discussed next). - Perhaps lesser known, OSObjects have hashes based on the memory to which they refer. So multiple OSObjects may represent the same memory which can lead to confusion about who frees the memory, if they are supposed to free it, their use in hashed collections and so on...see the next point. - You probably want to provide some safety nets so users don't produce memory leaks, general protection faults and any of these other nasty things we all hate. I was pleased with the memory protection scheme that was put into the OpenSSL bindings (8.6.2). With it we can protect the user against freeing memory that didn't belong to them, freeing memory that was already freed, a situation called 'fault due to pointer aliasing' where multiple objects refer to the same memory address....now one of them was freed and the others had no idea..they still think they are pointing to valid memory. We put some of this in LibUSB...but OpenSSL has the beefed up version. We use WeakIdentitySets (yss...Identity!) to track all instances created and the GC will notify when the OSObject is about to be garbage collected. There could be a whole page written just on GC finalization, as it can be misused, but as I say...it's a safety net. Freeing memory is of course good to remember...and the high-level API's of the OSObjects should be designed with that in mind. - I guess the bottom line is if you are satisfied with the way things have been modeled by the library in question, and don't have a situation where you have n-number of independent libraries that support the same need, and therefore need a common interface...then this may be good enough. 2-Layer Pattern: In this pattern we will be defining the desired interfaces and abstractions. The OSObject bindings will be trim...and will most likely just be dumb objects that simply bind to the memory they represent. They typically won't have that much behavior. The high-level layer will provide the interface...and will direct the actions of the lower-layer (OSObjects). Product Example: Database Drivers Tradoffs: - Obviously, you will do more work trying to design a one-interface-to-rule-them-all approach. - As stated, can be good if you have multiple native providers to interface/abstractions you are constructing. Another example is OpenSSL SSL/TLS support. This also uses smalltalk wrappers around the OSObjects. This would allow, for example, to switch out OpenSSL's SSL/TLS support with Amazon S2Ns version without having to change the interface classes to much. The reality is that OpenSSL's SSL/TLS objects have a rich API, so the wrappers do very little except formalize the interface. - If you are unhappy with the abstraction level at which the bindings expose behavior, it may be good to use this. For example, our Zip/Unzip support in the product has a Stream based implementation making it something that Smalltalkers would want to work with rather than the interface provided by the MZStream struct binding. - If you don't manage the separation well, this can make updating bindings far more difficult than a 1-layer approach. As new functionality is exposed in native bindings, it may be difficult to understand how your interface abstractions need to change or where. Especially in situations where one smalltalk object directs the actions of multiple OSObjects...it can just get hard. - It is expected that the Smalltalk wrappers will manage freeing native memory as necessary as they work with OSObjects. There could be situations where this isn't the case, but if it is..then you don't need memory trackers as much. To answer Richard's question, I'll just briefly say (since Lou will probably elaborate) that LibUSB's objects form a tree structure. And the top level guy is a Context. There is the notion of a default context so we added a Default classVar on the Context object. We also added a MemoryTracker on the application class providing the safety nets I discussed. Since these OSObjects form a tree structure...as nodes they have additional instance variables to describe the parent and children. LibUSB's functions don't necessarily provide accessors to these so we keep track of it within smalltalk. -- Seth On Wednesday, February 17, 2016 at 1:05:55 PM UTC-5, Richard Sargent wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi All, More about memory tracking. Actually this is about freeing OS memory that was obtained by your Smalltalk interface code or by the DLL to give you access to information. This memory needs to be freed when it is no longer needed. Memory obtained by the DLL, may need to be freed with a special DLL function depending upon how the memory was obtained. The memory tracking we are using in the LibUSB interface is a little more general than what Seth did in the OpenSSL interface so I will describe it here in general terms. We need a place to keep track of the memory objects that will need freeing. A class variable in the application class will do just fine. Seth called it MemoryTracker. It is a EsWeakIdentitySet defined to call a single argument method where the argument is the instance to be freed. When the garbage collector is about to collect an instance, the finalize action method is called.
The finalize action method checks to see that the instance (its parameter) is not nil and not undefined and then frees it. Overriding #free for the structures that map the memory allows an opportunity to manage the MemoryTracker set, do some clean up and call the special DLL function that needs to free the memory in the DLL. We called that method #nativeFree. The #nativeFree method of each OSStructure sub-class knows how to free itself (the DLL function call needed). To see exactly how its done, check out the LibUSB interface. Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi All, To continue our conversion about building an interface it seems that things like drivers can have an impact on the working of an interface. There aren't just newer versions of a driver there are also different flavors of drivers. So, if things don't seem to be making sense, check to see if a driver might be involved. See our thread on LibUSB for an example. Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Free forum by Nabble | Edit this page |