# Language Bindings [Language bindings](https://en.wikipedia.org/wiki/Language_binding) refers to wrappers to bridge 2 programming languages. This is used in P2PRC to extend calling P2PRC functions in other programming languages. Currently this is done by generating ```.so``` and ```.h``` from the Go compiler.
## How to build shared object files #### The easier way ```bash # Run make sharedObjects ``` #### Or the direct way ```bash # Run cd Bindings && go build -buildmode=c-shared -o p2prc.so ``` #### If successfully built: ```bash # Enter into the Bindings directory cd Bindings # List files ls # Find files p2prc.h p2prc.so ```
## Workings under the hood Below are a sample set of commands to open the bindings implementation. ``` # run cd Bindings/ # list files ls # search for file Client.go ``` ### In Client go There a few things to notice which are different from your standard Go programs: #### 1. We import "C" which means [Cgo](https://pkg.go.dev/cmd/cgo) is required. ```go import "C" ``` #### 2. All functions which are required to be called from other programming languages have comment such as. ```go //export // ------------ Example ---------------- // The function below allows to externally // to call the P2PRC function to start containers // in a specific node in the know list of nodes // in the p2p network. // Note: the comment "//export StartContainer". //export StartContainer func StartContainer(IP string) (output *C.char) { container, err := client.StartContainer(IP, 0, false, "", "") if err != nil { return C.CString(err.Error()) } return ConvertStructToJSONString(container) } ``` #### 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure). ```go // --------- Example ------------ //export StartContainer func StartContainer(IP string) (output *C.char) { container, err := client.StartContainer(IP, 0, false, "", "") if err != nil { return C.CString(err.Error()) } return ConvertStructToJSONString(container) } //export ViewPlugin func ViewPlugin() (output *C.char) { plugins, err := plugin.DetectPlugins() if err != nil { return C.CString(err.Error()) } return ConvertStructToJSONString(plugins) } ``` #### It is easy to notice that: - ```ConvertStructToJSONString()```: This is a helper function that convert a go object to JSON string initially and converts it to ```CString```. - ```(output *C.char)```: This is the return type for most of the functions. #### A Pseudo code to refer to the common function implementation shape could be represented as: ``` func (output *C.char) { , := () if != nil { return C.CString(.Error()) } return ConvertStructToJSONString() } ```
## Current languages supported - Python ### Build sample python program The easier way ```bash # Run make python # Expected ouput Output is in the Directory Bindings/python/export/ # Run cd Bindings/python/export/ # list files ls # Expected output SharedObjects/ p2prc.py ``` Above shows a generated folder which consists of a folder called "SharedObjects/" which consists of ```p2prc.so``` and ```p2prc.h``` files. ```p2prc.py``` refers to a sample python script calling P2PRC go functions. To start an any project to extend P2PRC with python, This generated folder can copied and created as a new git repo for P2PRC extensions scripted or used a reference point as proof of concept that P2PRC can be called from other programming languages.