Difference between revisions of "JS-ctypes"

Jump to navigation Jump to search
no edit summary
Line 17: Line 17:
# Write a JS module interfacing with js-ctypes and the C wrapper.
# Write a JS module interfacing with js-ctypes and the C wrapper.
# Fix existing JS code (gui.js, etc) to use the JS module.
# Fix existing JS code (gui.js, etc) to use the JS module.
'''Note''': Because of the number of layers, it is important to respect the convention on naming which differs from layer to layer.
Examples:
* '''component''': zimAccessor
* '''component path''': src/components/zimAccessor
* '''library name''': zimAccessor
* '''library path''': src/zimAccessor
* '''C++ library files''': zimAccessor.cpp zimAccessor.h
* '''C Wrapper files''': ZimAccessorWrapper.cpp ZimAccessorWrapper.h
* '''Tester path''': src/zimTester/
* '''C++ tester file''': zimTester.cpp
* '''C Wrapper tester file''': zimCTester.c


=== Rewrite the C++ component into a C++ library ===
=== Rewrite the C++ component into a C++ library ===
Line 37: Line 50:
* C++ Component code [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/components/zimAccessor/zimAccessor.cpp?revision=2920&view=markup example]
* C++ Component code [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/components/zimAccessor/zimAccessor.cpp?revision=2920&view=markup example]
* C++ library [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/zimAccessor.cpp?revision=2920&view=markup example]
* C++ library [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/zimAccessor.cpp?revision=2920&view=markup example]
* C++ library header [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/zimAccessor.h?revision=2811&view=markup example]


Rules to embrace/respect:
Rules to embrace/respect:
Line 46: Line 60:
# don't add features while you port to keep it understandable and revert-able.
# don't add features while you port to keep it understandable and revert-able.


The component uses no header file (it is generated from IDL at compile time and is really verbose) so you also need to write it manually. header file [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/zimAccessor.h?revision=2811&view=markup example].
The component uses no header file (it is generated from IDL at compile time and is really verbose) so you also need to write it manually. Refer to example.
 
=== Write a C++ program testing the C++ API ===
 
Instead of writing a program to test the features of the API, we should write unit tests but I have no prior experience with unit testing with C/C++ so I choose the loose way.
Feel free to improve that.
 
The idea here is just to make sure that all methods are available and working as expected.
 
* C++ library [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/zimAccessor.h?revision=2811&view=markup header file]
* C++ tester [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimTester/zimTester.cpp?revision=2920&view=markup source]
 
I'm not very proud of it, a lot of stuff are hard coded and while it gets a ZIM as argument, it expects the swahili zim to test everything.
 
=== Write a C Wrapper around the C++ API ===
 
js-ctypes (and ctypes) only works with C code and not with C++. Because our code base is in C++ (for good reasons), we need to add a C layer to interface with the C++ library.
This is done by creating a C++ library (exported as C) containing only functions which would each call the C++ API.
We'll add a couple functions to create/destroy the instance of the C++ class and each function will accept a pointer to the instance as parameter.
 
* C Wrapper [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/ZimAccessorWrapper.cpp?revision=HEAD&view=markup example]
* C wrapper header [http://kiwix.svn.sourceforge.net/viewvc/kiwix/moulinkiwix/src/zimAccessor/ZimAccessorWrapper.h?revision=HEAD&view=markup example]
 
Rules:
# Create a void pointer type to match the class pointer.
# Create functions to crete/destroy the class instance.
# All functions are prefixed with library name (and keep case)
# All functions have previously created type as first argument
# expect C types as input (''char *'')
# convert ''char *'' to ''string'' inside your function
# convert outputed ''string'' to ''char *''
# return the actual data. Most of the time, we only have one return variable. Use that as return type for the wrapper. It's easier and cleaner from the JS perspective.
 
Header example
<blockquote><source lang="cpp">
typedef void * HZIMCLASS;
HIMCLASS ZimAccessor_Create( void );
void ZimAccessor_Destroy( HZIMCLASS h );
const char* ZimAccessor_GetPageUrlFromTitle( HZIMCLASS h, char* url);
</source></blockquote>
 
Source example
<blockquote><source lang="cpp">
/* creates instance of ZimAccessor */
HZIMCLASS ZimAccessor_Create( void ) {
    ZimAccessor * zimAccessor = new ZimAccessor(0);
 
    // Return its pointer (opaque)
    return (HZIMCLASS)zimAccessor;
}
 
/* Delete instance of ZimAccessor */
void ZimAccessor_Destroy( HZIMCLASS h ) {
    assert(h != NULL);
 
    // Convert from handle to ZimAccessor pointer
    ZimAccessor * zimAccessor = (ZimAccessor *)h;
 
    delete zimAccessor;
}
 
/* Return a page url fronm title */
const char* ZimAccessor_GetPageUrlFromTitle( HZIMCLASS h, char* title) {
    assert(h != NULL);
 
    ZimAccessor * zimAccessor = (ZimAccessor *)h;
 
    string cptitle = string(title);
    string url = "";
    zimAccessor->GetPageUrlFromTitle(cptitle, url);
    return url.c_str();
}
</source></blockquote>
 
== Tips ==
 
* .so libs in xulrunner folder


== Remaining work ==
== Remaining work ==


* unicode
* unicode
* makefiles
7,801

edits

Navigation menu