Skip to content

Commit

Permalink
Export C functions for other languages
Browse files Browse the repository at this point in the history
  • Loading branch information
kabili207 committed May 19, 2023
1 parent b1c0f00 commit 0d6d087
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@ else()

add_library(decoder
src/decoder.cpp
src/decoder_c.cpp
)

set_target_properties(decoder PROPERTIES
PUBLIC_HEADER shared/theengs.h)

target_include_directories(decoder
PUBLIC
$<INSTALL_INTERFACE:arduino_json>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/arduino_json/src>
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
)

Expand Down
21 changes: 21 additions & 0 deletions examples/go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Go demo

## Prerequisites

The decoder library should be compiled statically when using it with Go.

From the decoder root folder

```sh
mkdir -p build
cd build
cmake -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF ..
make
```

# Running
The example can now be ran

```sh
go run decode.go
```
69 changes: 69 additions & 0 deletions examples/go/decoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

// #cgo LDFLAGS: -lstdc++ -L../../build -ldecoder
// #include "../../include/shared/theengs.h"
// #include "stdlib.h"
import "C"

import (
"log"
"unsafe"
)

type TheengsDecoder struct {
ptr unsafe.Pointer
}

func NewDecoder() TheengsDecoder {
return TheengsDecoder{
ptr: C.Theengs_NewDecoder(),
}
}

func (d TheengsDecoder) Destroy() {
C.Theengs_DestroyDecoder(d.ptr)
}

func (d TheengsDecoder) DecodeBLE(json_data string) string {
cs_data := C.CString(json_data)
cs_result := C.Theengs_DecodeBLE(d.ptr, cs_data)
result := C.GoString(cs_result)
C.free(unsafe.Pointer(cs_data))
C.free(unsafe.Pointer(cs_result))
return result
}

func (d TheengsDecoder) GetProperties(model_id string) string {
cs_model := C.CString(model_id)
cs_result := C.Theengs_GetProperties(d.ptr, cs_model)
result := C.GoString(cs_result)
C.free(unsafe.Pointer(cs_model))
C.free(unsafe.Pointer(cs_result))
return result
}

func (d TheengsDecoder) GetAttribute(model_id string, attribute string) string {
cs_model := C.CString(model_id)
cs_attr := C.CString(attribute)
cs_result := C.Theengs_GetAttribute(d.ptr, cs_model, cs_attr)
result := C.GoString(cs_result)
C.free(unsafe.Pointer(cs_model))
C.free(unsafe.Pointer(cs_attr))
C.free(unsafe.Pointer(cs_result))
return result
}

func main() {

json_data := `{"id":"redacted","mac_type":0,"adv_type":0,"name":"LYWSD02","rssi":-67,"servicedata":"70205b043941e480012ee7090a10012500","servicedatauuid":"0xfe95"}`

decoder := NewDecoder()
data := decoder.DecodeBLE(json_data)
props := decoder.GetProperties("LYWSD02")
brand := decoder.GetAttribute("LYWSD02", "brand")
model := decoder.GetAttribute("LYWSD02", "model")

log.Println(data)
log.Println(props)
log.Printf("brand: %v, model: %v\n", brand, model)
}
2 changes: 2 additions & 0 deletions examples/go/dummy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Go won't use the C++ linker unless it detects at least one cpp file
// This file serves no other purpose
39 changes: 39 additions & 0 deletions include/shared/theengs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
TheengsDecoder - Decode things and devices
Copyright: (c)Florian ROBERT
This file is part of TheengsDecoder.
TheengsDecoder is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TheengsDecoder is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _THEENGS_H_
#define _THEENGS_H_

#ifdef __cplusplus
extern "C" {
#endif

void* Theengs_NewDecoder();
void Theengs_DestroyDecoder(void* decoder);
const char* Theengs_DecodeBLE(void* decoder, const char* json_data);
const char* Theengs_GetProperties(void* decoder, const char* model_id);
const char* Theengs_GetAttribute(void* decoder, const char* model_id, const char* attribute);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // _THEENGS_H_
64 changes: 64 additions & 0 deletions src/decoder_c.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
TheengsDecoder - Decode things and devices
Copyright: (c)Florian ROBERT
This file is part of TheengsDecoder.
TheengsDecoder is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TheengsDecoder is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <string.h>

#include "decoder.h"
#include "shared/theengs.h"

// Utility function local to the bridge's implementation
TheengsDecoder* AsDecoder(void* decoder) { return reinterpret_cast<TheengsDecoder*>(decoder); }

void* Theengs_NewDecoder() {
auto decoder = new TheengsDecoder();
return decoder;
}

void Theengs_DestroyDecoder(void* decoder) {
AsDecoder(decoder)->~TheengsDecoder();
}

const char* Theengs_DecodeBLE(void* decoder, const char* json_data) {
StaticJsonDocument<1024> doc;
DeserializationError err = deserializeJson(doc, json_data);
if (!err) {
JsonObject bleObject;
bleObject = doc.as<JsonObject>();

if (AsDecoder(decoder)->decodeBLEJson(bleObject) >= 0) {
std::string buf;
serializeJson(bleObject, buf);
return strdup(buf.c_str());
}
}
return "";
}

const char* Theengs_GetProperties(void* decoder, const char* model_id) {
std::string props = AsDecoder(decoder)->getTheengProperties(model_id);
return strdup(props.c_str());
}

const char* Theengs_GetAttribute(void* decoder, const char* model_id, const char* attribute) {
std::string attrs = AsDecoder(decoder)->getTheengAttribute(model_id, attribute);
return strdup(attrs.c_str());
}

0 comments on commit 0d6d087

Please sign in to comment.