B4R Tutorial Creating libraries for B4R

Discussion in 'B4R Tutorials' started by Erel, Apr 12, 2016.

Similar threads

B4A Code Snippet [B4X] Join arrays of bytes
B4R Tutorial Memory, Variables and Objects
B4R Tutorial Strings and Bytes
Games [XUI2D] Example Pack
B4R Code Snippet Base64 decoding
  1. Erel

    Erel Administrator Staff Member Licensed User

    Libraries are written in C++.
    Libraries are made of a single h file and one or more cpp files. Libraries can also include other h files which will not be exposed.

    All the files should be in the same folder.
    The attached h2xml jar reads the h file and creates the xml file that is used by the IDE.
    It is a command line program.

    You can run it with:
    Code:
    java -jar B4Rh2xml <path to h file> <output file>
    As the IDE libraries source code is available, this is the best way to learn how to build libraries.

    Start with a simple library such as rEEPROM.

    Personally I'm using Notepad++ to write the libraries.
    The IDE doesn't cache the libraries source (unlike in B4A). So you can save the file and run the project to test it.
    If the signature was changed then you need to run the h2xml tool and then right click on the libraries tab and choose Refresh.

    Metadata attributes (attribute case is not important):

    //~Version - The library version.
    //~DependsOn - Can appear multiple times. Adds a dependency on an external h file.
    //~ShortName - Each exposed class should have this attribute. This is the name that will appear in the IDE.
    //~Event - Can appear multiple times. Used by the IDE to autocomplete event subs.
    //~Author - Library author

    Rules, tips and notes

    Libraries should avoid using the heap (malloc or new should not be used).

    - Most libraries wrap another object. There are cases where you need to call the object constructor and you can only do it when the user calls the Initialize method.
    This is the case for example in rLiquidCrystal library.
    The solution is to create an array of bytes (named backend in this example) and then use placement new instead of new. This way we can generate a new object in the already allocated buffer.

    - Polling. If you need to call a method every loop iteration then you can add it to the PollerList.
    See Pin::AddListener for an example. Note that you can only add static methods. Pass a pointer to the class instance as the tag value.
    It is possible to remove the "polling". It is a bit more complicated. You can see it in rMQTT implementation.

    - Using the stack buffer.

    How can your method return a new object if it cannot use the heap?
    How can Common::NumberFormat return a string?

    In many cases the solution is to let the user pass an array to your method and then your method will use the array. However this is not always convenient. This is why B4R maintains another stack.
    You can use this stack for allocations. It will be popped when the calling sub ends.

    Simple example: ByteConverter::convertBytesToArray. It is simple because it only creates the Array object on the B4R stack.

    More complicated example: ByteConverter::HexToBytes. In this case the array with its data are created on the B4R stack.

    - Interrupts - The B4R code should not be called from an interrupt. Instead you should call pollers.setInterrupt. See rWire library (WriteSlave::receiveEvent).

    - Raising events - Any parameter with a type that starts with Sub will be treated as a "sub name". Practically the compiler will remove the quotes and lower case the string value. Your code will receive a function pointer.
    You can use the types declared with typedef in rCore.h or use your own types.

    - Pointers and objects - Only pointers to objects should be exposed to B4R.

    Please use the libraries developers questions for any question: https://www.b4x.com/android/forum/forums/libraries-developers-questions.77/
     

    Attached Files:

  2. jarda

    jarda Member Licensed User

    Hi
    How can I integrate this source code. For example, as a library. (B4R)
    Can this be done?

    Thanks

    Jarek
     

    Attached Files:

    • TFT.ZIP
      File size:
      45.9 KB
      Views:
      252
  3. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this.
     
  4. Cableguy

    Cableguy Expert Licensed User

    Hi Erel,

    I'm trying to build my first wrapper, but can't even create the xml from the .h file.

    Code:
    D:\psapg\NeoPixelWrap>java -jar B4Rh2xml.jar Adafruit_NeoPixel.h B4R_NeoPixel
    Error parsing: Adafruit_NeoPixel(void);
    parser._parsemethod (java line: 
    527)
    java.lang.NumberFormatException: 
    For input string"error"
            at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
            at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
            at java.lang.Double.parseDouble(Unknown Source)
            at b4j.example.parser._parsemethod(parser.java:
    527)
            at b4j.example.parser._parseline(parser.java:
    464)
            at b4j.example.parser._parseh(parser.java:
    422)
            at b4j.example.parser._
    parse(parser.java:267)
            at b4j.example.main._appstart(main.java:
    46)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    93)
            at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    84)
            at b4j.example.main.main(main.java:
    29)
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    Can you post the h file?
     
  6. Cableguy

    Cableguy Expert Licensed User

    you can find it here!
     
    Last edited: Jul 31, 2016
  7. Erel

    Erel Administrator Staff Member Licensed User

    You cannot convert this h file to xml. You need to create a wrapper that accesses these methods.
     
  8. Cableguy

    Cableguy Expert Licensed User

    So, how do I do that?
    Perhaps not the easiest to start with?
    Can it be done using a code module + inline c combo?
     
    Peter Simpson likes this.
  9. Erel

    Erel Administrator Staff Member Licensed User

  10. Cableguy

    Cableguy Expert Licensed User

    So I guess I need to wish for it!
     
  11. Buks

    Buks Member Licensed User

    Has anyone managed to use the Arduino Ciao Library? There is a special version of Arduino Uno (Arduino Uno WIFI) that can make use of this library for network interaction. It does not seem to work with inline C - no errors, but data does not update. It would really be very nice to access all the functionalities of the Uno WIFI from B4R.
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    Seems to me that this library is more useful when for Phyton programmers.

    B4R supports higher level communication methods such as MQTT or WebSockets. It is quite simple to communicate with other components, especially when developing with the other B4X tools.
     
  13. Peter Simpson

    Peter Simpson Expert Licensed User

    It would be nice to have a tutorial video on creating more complicated B4R libraries, lets say it based on Adafruit_NeoPixel (which has already been wrapped by @Erel). I actually want to use B4R to create a project BUT no library, so I've just started it in Arduino instead which is a nightmare compared to B4R.

    Basically I ran into the same issues as what's in post #4 :(

    Untitled-2.png

    The above looks Martian to me o_O
     
    Last edited: Feb 1, 2017
  14. Erel

    Erel Administrator Staff Member Licensed User

    miker2069 likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice