Bladeren bron

A version that almost works.

ZRY 1 jaar geleden
bovenliggende
commit
017be64055

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+/zrfu-macro/target/
+/zry-rust-ffi-utils/target/

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/zry-rust-ffi-utils.iml" filepath="$PROJECT_DIR$/.idea/zry-rust-ffi-utils.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>

+ 17 - 0
.idea/zry-rust-ffi-utils.iml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/example/rust/zrfu-test/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/zry-rust-ffi-utils/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/zrfu-macro/src" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/zry-rust-ffi-utils/target" />
+      <excludeFolder url="file://$MODULE_DIR$/example/rust/zrfu-test/target" />
+      <excludeFolder url="file://$MODULE_DIR$/example/dist" />
+      <excludeFolder url="file://$MODULE_DIR$/zrfu-macro/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 2 - 0
example/.gitignore

@@ -0,0 +1,2 @@
+dist/
+/rust/zrfu-test/target/

+ 30 - 0
example/Makefile

@@ -0,0 +1,30 @@
+DIST = dist
+RUST_DIR = rust/zrfu-test
+GO_DIR = go
+
+.PHONY : all
+.PHONY : rustdll
+.PHONY : rust_build
+.PHONY : goexe
+.PHONY : clean
+
+all : rustdll goexe
+
+rustdll : $(DIST)/zrfu_test_rust.dll
+
+$(DIST)/zrfu_test_rust.dll : $(RUST_DIR)/target/debug/zrfu_test_rust.dll
+	cp $^ $@
+
+$(RUST_DIR)/target/debug/zrfu_test_rust.dll : rust_build
+
+rust_build : $(RUST_DIR)/
+	cd $(RUST_DIR) && cargo build
+
+goexe : $(DIST)/test.exe
+
+$(DIST)/test.exe : $(GO_DIR)/
+	cd $(GO_DIR) && go mod tidy -e
+	cd $(GO_DIR) && go build -o ../$@ .
+
+clean :
+	rm -fr ./$(DIST)/*

+ 3 - 0
example/go/go.mod

@@ -0,0 +1,3 @@
+module zrfu-test
+
+go 1.19

+ 0 - 0
example/go/go.sum


+ 136 - 0
example/go/main.go

@@ -0,0 +1,136 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	zrfu "git.swzry.com/zry/zry-rust-ffi-utils/go-zrfu"
+	"io"
+)
+
+type TestCBORStruct struct {
+	A string                 `cbor:"a"`
+	B int64                  `cbor:"b"`
+	C map[string]string      `cbor:"c"`
+	D map[string]interface{} `cbor:"d"`
+}
+
+func main() {
+	lib, err := zrfu.LoadDyLib("zrfu_test_rust.dll")
+	if err != nil {
+		fmt.Println("failed init dll: ", err)
+		return
+	}
+	lib.SetDebugMode(true)
+	bv1, err := zrfu.NewBytesVec(lib)
+	defer bv1.Close()
+	if err != nil {
+		fmt.Println("failed new BytesVec: ", err)
+		return
+	}
+	fmt.Println("Write 'neko: '...")
+	n, err := bv1.Write([]byte("neko: "))
+	if err != nil {
+		fmt.Println("failed write to BytesVec: ", err)
+		return
+	}
+	fmt.Println(n, "byte(s) written into BytesVec.")
+	l, err := bv1.Len()
+	if err != nil {
+		fmt.Println("failed get length of BytesVec: ", err)
+		return
+	}
+	fmt.Println("Now length=", l, " byte(s).")
+	fmt.Println("Write 'nya~'...")
+	n, err = bv1.Write([]byte("nya~"))
+	if err != nil {
+		fmt.Println("failed write to BytesVec: ", err)
+		return
+	}
+	fmt.Println(n, "byte(s) written into BytesVec.")
+	l, err = bv1.Len()
+	if err != nil {
+		fmt.Println("failed get length of BytesVec: ", err)
+		return
+	}
+	fmt.Println("Now length=", l, " byte(s).")
+	rdat, err := io.ReadAll(bv1)
+	if err != nil {
+		fmt.Println("failed read from BytesVec: ", err)
+		return
+	}
+	fmt.Println("Read from BytesVec: ", string(rdat))
+
+	fmt.Println("======== Call Func Test ========")
+	caller, err := zrfu.NewZRFUCaller(lib)
+	if err != nil {
+		fmt.Println("failed init ZRFUCaller: ", err)
+		return
+	}
+
+	fmt.Println("---- TestFuncAR ----")
+	argar := &TestCBORStruct{
+		A: "hello, TestFuncAR",
+		B: 114514,
+		C: map[string]string{
+			"nya":   "meow~",
+			"hello": "world",
+		},
+		D: map[string]interface{}{
+			"test":   1919.810,
+			"satori": 5,
+		},
+	}
+	var retar TestCBORStruct
+	err = caller.CallAR("TestFuncAR", argar, &retar)
+	if err != nil {
+		fmt.Println("failed call proc: ", err)
+		return
+	}
+	fmt.Println(" ---- TestFuncAR Result ----")
+	JsonPrintUtil(retar)
+
+	fmt.Println("---- TestFuncA ----")
+	arga := &TestCBORStruct{
+		A: "hello, TestFuncA",
+		B: 1919810,
+		C: map[string]string{
+			"nya":   "cat",
+			"hello": "gensokyo",
+		},
+		D: map[string]interface{}{
+			"test":   114.514,
+			"satori": 5,
+		},
+	}
+	err = caller.CallA("TestFuncA", arga)
+	if err != nil {
+		fmt.Println("failed call proc: ", err)
+		return
+	}
+
+	fmt.Println("---- TestFuncR ----")
+	var retr TestCBORStruct
+	err = caller.CallR("TestFuncR", &retr)
+	if err != nil {
+		fmt.Println("failed call proc: ", err)
+		return
+	}
+	fmt.Println(" ---- TestFuncR Result ----")
+	JsonPrintUtil(retar)
+
+	fmt.Println("---- TestFuncN ----")
+	err = caller.CallN("TestFuncN")
+	if err != nil {
+		fmt.Println("failed call proc: ", err)
+		return
+	}
+}
+
+func JsonPrintUtil(v interface{}) {
+	jd, err := json.MarshalIndent(v, "\t", "  ")
+	if err != nil {
+		fmt.Println("Failed encode json for debug: ", err)
+		return
+	}
+	fmt.Println(string(jd))
+}

+ 370 - 0
example/rust/zrfu-test/Cargo.lock

@@ -0,0 +1,370 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bytebuffer"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce2468af960a9069ae7f77b6c16836e0ccc13f0caf8c8856b942924241c72f7b"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "ciborium"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "concurrent-hashmap"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b497d3441e4e31ef52273f344aacf0a24d28a353837451a45df9b3e9cf7d44a"
+dependencies = [
+ "spin",
+]
+
+[[package]]
+name = "cstr"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aa998c33a6d3271e3678950a22134cd7dd27cef86dee1b611b5b14207d1d90b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "ffi-support"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27838c6815cfe9de2d3aeb145ffd19e565f577414b33f3bdbf42fe040e9e0ff6"
+dependencies = [
+ "lazy_static",
+ "log",
+]
+
+[[package]]
+name = "half"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.143"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "num_enum"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+
+[[package]]
+name = "serde"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "spin"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14db77c5b914df6d6173dda9a3b3f5937bd802934fa5edaf934df06a3491e56f"
+
+[[package]]
+name = "strum"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
+
+[[package]]
+name = "strum_macros"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
+
+[[package]]
+name = "toml_edit"
+version = "0.19.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
+dependencies = [
+ "indexmap",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "winnow"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "zrfu-macro"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "zrfu-test"
+version = "0.1.0"
+dependencies = [
+ "ciborium",
+ "serde",
+ "zrfu-macro",
+ "zry-rust-ffi-utils",
+]
+
+[[package]]
+name = "zry-rust-ffi-utils"
+version = "0.1.0"
+dependencies = [
+ "bytebuffer",
+ "ciborium",
+ "ciborium-io",
+ "concurrent-hashmap",
+ "cstr",
+ "ffi-support",
+ "lazy_static",
+ "libc",
+ "num_enum",
+ "once_cell",
+ "serde",
+ "strum",
+ "strum_macros",
+]

+ 14 - 0
example/rust/zrfu-test/Cargo.toml

@@ -0,0 +1,14 @@
+[package]
+name = "zrfu-test"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+zry-rust-ffi-utils = { path = "../../../zry-rust-ffi-utils" }
+serde = { version = "1.0", features = ["derive"] }
+ciborium = "0.2.1"
+zrfu-macro = { path = "../../../zrfu-macro" }
+
+[lib]
+name = "zrfu_test_rust"
+crate-type = ["cdylib"]

+ 132 - 0
example/rust/zrfu-test/src/lib.rs

@@ -0,0 +1,132 @@
+
+extern crate zry_rust_ffi_utils;
+
+use zry_rust_ffi_utils::bytes_vec::ZRFUBytesVec;
+use zry_rust_ffi_utils::caller::ProcCallerLibSide;
+use zry_rust_ffi_utils::proc::{ZRFUProcArgs, ZRFUProcInstanceTrait, ZRFUProcReturn};
+use zry_rust_ffi_utils::proc::ZRFUProcResultCode;
+use serde::{Serialize, Deserialize};
+use ciborium::{cbor, Value};
+use zry_rust_ffi_utils::{proc_def_ar, proc_def_a, proc_def_r, proc_def_n};
+use zrfu_macro::zrfu_proc_def;
+
+#[no_mangle]
+pub extern "C" fn LibWithZRFU_Init(caller: &dyn ProcCallerLibSide){
+    caller.register_proc(String::from("TestFuncAR"), TestProcAR::factory);
+    caller.register_proc(String::from("TestFuncA"), TestProcA::factory);
+    caller.register_proc(String::from("TestFuncR"), TestProcR::factory);
+    caller.register_proc(String::from("TestFuncN"), TestProcN::factory);
+}
+
+
+#[derive(Debug, Serialize, Deserialize)]
+struct TestProcCborIn {
+    a: String,
+    b: i64,
+    c: Value,
+    d: Value,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct TestProcCborOut {
+    a: String,
+    b: i64,
+    c: Value,
+    d: Value,
+}
+
+zrfu_proc_def!{
+    proc fn TestProcAR (argsdata: TestProcCborIn) -> (retdata: TestProcCborOut) {
+        println!("hello, this function '{}' has args and return.", self.proc_name.as_str());
+        println!("args data: {:?}", argsdata);
+        let retdata = TestProcCborOut{
+            a: argsdata.a.clone(),
+            b: argsdata.b,
+            c: argsdata.c.clone(),
+            d: argsdata.d.clone(),
+        };
+    }
+}
+
+zrfu_proc_def!{
+    proc fn TestProcA (argsdata: TestProcCborIn) -> () {
+        println!("hello, this function '{}' has args but no return.", self.proc_name.as_str());
+        println!("args data: {:?}", argsdata);
+    }
+}
+
+zrfu_proc_def!{
+    proc fn TestProcR () -> (retdata: TestProcCborOut) {
+        println!("hello, this function '{}' has return but no args.", self.proc_name.as_str());
+        let c_res = cbor!({
+            "reimu" => "hakurei",
+            "satori" =>  "komeiji",
+            "koishi" =>  "komeiji",
+        });
+        let d_res = cbor!({
+            "cirno" => 9,
+            "satori" => 5,
+            "remilia" => "scarlet",
+        });
+        let retdata = TestProcCborOut{
+            a: String::from("hello, gensokyo"),
+            b: 123456,
+            c: c_res.unwrap(),
+            d: d_res.unwrap(),
+        };
+    }
+}
+
+zrfu_proc_def!{
+    proc fn TestProcN () -> () {
+        println!("hello, this function '{}' has neither args nor return.", self.proc_name.as_str());
+    }
+}
+
+/*
+proc_def_ar!(
+    TestProcAR (TestProcCborIn as argsdata ; TestProcCborOut as retdata) {
+        println!("hello, this function '{}' has args and return.", self.proc_name);
+        println!("args data: {:?}", argsdata);
+        let retdata = TestProcCborOut{
+            a: argsdata.a.clone(),
+            b: argsdata.b,
+            c: argsdata.c.clone(),
+            d: argsdata.d.clone(),
+        };
+    }
+);
+
+proc_def_a!(
+    TestProcA (TestProcCborIn as argsdata) {
+        println!("hello, this function '{}' has args but has no return.", self.proc_name);
+        println!("args data: {:?}", argsdata);
+    }
+);
+
+proc_def_r!(
+    TestProcR (TestProcCborOut as retdata) {
+        println!("hello, this function '{}' has no args but has return.", self.proc_name);
+        let retdata = TestProcCborOut{
+            a: String::from("hello, gensokyo"),
+            b: 123456,
+            c: cbor!({
+                "reimu" => "hakurei",
+                "satori" =>  "komeiji",
+                "koishi" =>  "komeiji",
+            }),
+            d: cbor!({
+                "cirno" => 9,
+                "satori" => 5,
+                "remilia" => "scarlet",
+            }),
+        };
+    }
+);
+
+proc_def_n!(
+    TestProcN () {
+        println!("hello, this function '{}' has neither args nor return.", self.proc_name);
+    }
+);
+*/

+ 79 - 0
go-zrfu/bytes_vec.go

@@ -0,0 +1,79 @@
+package go_zrfu
+
+import (
+	"io"
+	"unsafe"
+)
+
+var _ = io.ReadWriter(&BytesVec{})
+
+type BytesVec struct {
+	lib *ZRFUDyLib
+	h   uint64
+}
+
+func NewBytesVec(lib *ZRFUDyLib) (*BytesVec, error) {
+	v := &BytesVec{
+		lib: lib,
+		h:   0,
+	}
+	var hbuf uint64
+	hptr := uintptr(unsafe.Pointer(&hbuf))
+	_, err := lib.procCall(lib.procBVNew, hptr)
+	if err != nil {
+		return nil, err
+	}
+	v.h = hbuf
+	return v, nil
+}
+
+func (b BytesVec) Read(p []byte) (n int, err error) {
+	hptr := uintptr(unsafe.Pointer(&b.h))
+	l := len(p)
+	bufptr := uintptr(unsafe.Pointer(&p[0]))
+	r, err := b.lib.procCall(b.lib.procBVRead, hptr, bufptr, uintptr(l))
+	if err != nil {
+		return 0, err
+	}
+	if r == 0 {
+		return 0, io.EOF
+	}
+	return int(r), nil
+}
+
+func (b BytesVec) Write(p []byte) (n int, err error) {
+	hptr := uintptr(unsafe.Pointer(&b.h))
+	l := len(p)
+	bufptr := uintptr(unsafe.Pointer(&p[0]))
+	r, err := b.lib.procCall(b.lib.procBVWrite, hptr, bufptr, uintptr(l))
+	if err != nil {
+		return 0, err
+	}
+	return int(r), nil
+}
+
+func (b BytesVec) Close() error {
+	hptr := uintptr(unsafe.Pointer(&b.h))
+	_, err := b.lib.procCall(b.lib.procBVDel, hptr)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (b BytesVec) Len() (int, error) {
+	hptr := uintptr(unsafe.Pointer(&b.h))
+	l, err := b.lib.procCall(b.lib.procBVLen, hptr)
+	if err != nil {
+		return 0, err
+	}
+	return int(l), nil
+}
+
+func (b BytesVec) Handle() uint64 {
+	return b.h
+}
+
+func (b BytesVec) HandlePtr() uintptr {
+	return uintptr(unsafe.Pointer(&b.h))
+}

+ 133 - 0
go-zrfu/caller.go

@@ -0,0 +1,133 @@
+package go_zrfu
+
+import (
+	"fmt"
+	cbor "github.com/fxamacker/cbor/v2"
+)
+
+type ZRFUCaller struct {
+	lib *ZRFUDyLib
+}
+
+func NewZRFUCaller(lib *ZRFUDyLib) (*ZRFUCaller, error) {
+	c := &ZRFUCaller{
+		lib: lib,
+	}
+	_, err := lib.procCall(lib.procPCInit)
+	if err != nil {
+		return nil, fmt.Errorf("error in init proc caller: %v", err)
+	}
+	return c, nil
+}
+
+func (c *ZRFUCaller) CallN(procName string) error {
+	pnbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: NewBytesVec: %v", err)
+	}
+	defer pnbv.Close()
+	cben := cbor.NewEncoder(pnbv)
+	err = cben.Encode(procName)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: CBOREncoding: %v", err)
+	}
+	_, err = c.lib.procCall(c.lib.procPCCall, pnbv.HandlePtr(), 0, 0)
+	if err != nil {
+		return fmt.Errorf("error in call proc: ProcCall: %v", err)
+	}
+	return nil
+}
+
+func (c *ZRFUCaller) CallAR(procName string, argData interface{}, retData interface{}) error {
+	pnbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: NewBytesVec: %v", err)
+	}
+	defer pnbv.Close()
+	argbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: Args: NewBytesVec: %v", err)
+	}
+	defer argbv.Close()
+	retbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: RetVal: NewBytesVec: %v", err)
+	}
+	defer retbv.Close()
+	cben := cbor.NewEncoder(pnbv)
+	err = cben.Encode(procName)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: CBOREncoding: %v", err)
+	}
+	argen := cbor.NewEncoder(argbv)
+	err = argen.Encode(argData)
+	if err != nil {
+		return fmt.Errorf("error in call proc: Args: CBOREncoding: %v", err)
+	}
+	_, err = c.lib.procCall(c.lib.procPCCall, pnbv.HandlePtr(), argbv.HandlePtr(), retbv.HandlePtr())
+	if err != nil {
+		return fmt.Errorf("error in call proc: ProcCall: %v", err)
+	}
+	retde := cbor.NewDecoder(retbv)
+	err = retde.Decode(retData)
+	if err != nil {
+		return fmt.Errorf("error in call proc: RetVal: CBORDecoding: %v", err)
+	}
+	return nil
+}
+
+func (c *ZRFUCaller) CallA(procName string, argData interface{}) error {
+	pnbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: NewBytesVec: %v", err)
+	}
+	defer pnbv.Close()
+	argbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: Args: NewBytesVec: %v", err)
+	}
+	defer argbv.Close()
+	cben := cbor.NewEncoder(pnbv)
+	err = cben.Encode(procName)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: CBOREncoding: %v", err)
+	}
+	argen := cbor.NewEncoder(argbv)
+	err = argen.Encode(argData)
+	if err != nil {
+		return fmt.Errorf("error in call proc: Args: CBOREncoding: %v", err)
+	}
+	_, err = c.lib.procCall(c.lib.procPCCall, pnbv.HandlePtr(), argbv.HandlePtr(), 0)
+	if err != nil {
+		return fmt.Errorf("error in call proc: ProcCall: %v", err)
+	}
+	return nil
+}
+
+func (c *ZRFUCaller) CallR(procName string, retData interface{}) error {
+	pnbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: NewBytesVec: %v", err)
+	}
+	defer pnbv.Close()
+	retbv, err := NewBytesVec(c.lib)
+	if err != nil {
+		return fmt.Errorf("error in call proc: RetVal: NewBytesVec: %v", err)
+	}
+	defer retbv.Close()
+	cben := cbor.NewEncoder(pnbv)
+	err = cben.Encode(procName)
+	if err != nil {
+		return fmt.Errorf("error in call proc: FuncName: CBOREncoding: %v", err)
+	}
+	_, err = c.lib.procCall(c.lib.procPCCall, pnbv.HandlePtr(), 0, retbv.HandlePtr())
+	if err != nil {
+		return fmt.Errorf("error in call proc: ProcCall: %v", err)
+	}
+	retde := cbor.NewDecoder(retbv)
+	err = retde.Decode(retData)
+	if err != nil {
+		return fmt.Errorf("error in call proc: RetVal: CBORDecoding: %v", err)
+	}
+	return nil
+}

+ 69 - 0
go-zrfu/dylib.go

@@ -0,0 +1,69 @@
+package go_zrfu
+
+import (
+	"github.com/ying32/dylib"
+)
+
+const (
+	PROCNAME_DBG_ON  = "ZRFU_Debug_On"
+	PROCNAME_DBG_OFF = "ZRFU_Debug_Off"
+
+	PROCNAME_BV_NEW   = "ZRFU_BytesVec_New"
+	PROCNAME_BV_DEL   = "ZRFU_BytesVec_Del"
+	PROCNAME_BV_LEN   = "ZRFU_BytesVec_Len"
+	PROCNAME_BV_WRITE = "ZRFU_BytesVec_Write"
+	PROCNAME_BV_READ  = "ZRFU_BytesVec_Read"
+
+	PROCNAME_PC_INIT = "ZRFU_Proc_Init"
+	PROCNAME_PC_CALL = "ZRFU_Proc_Call"
+)
+
+type ZRFUDyLib struct {
+	dll         *dylib.LazyDLL
+	procDbgOn   *dylib.LazyProc
+	procDbgOff  *dylib.LazyProc
+	procBVNew   *dylib.LazyProc
+	procBVDel   *dylib.LazyProc
+	procBVLen   *dylib.LazyProc
+	procBVWrite *dylib.LazyProc
+	procBVRead  *dylib.LazyProc
+	procPCInit  *dylib.LazyProc
+	procPCCall  *dylib.LazyProc
+}
+
+func LoadDyLib(name string) (*ZRFUDyLib, error) {
+	dll := dylib.NewLazyDLL(name)
+	zdl := &ZRFUDyLib{
+		dll: dll,
+
+		procDbgOn:  dll.NewProc(PROCNAME_DBG_ON),
+		procDbgOff: dll.NewProc(PROCNAME_DBG_OFF),
+
+		procBVNew:   dll.NewProc(PROCNAME_BV_NEW),
+		procBVDel:   dll.NewProc(PROCNAME_BV_DEL),
+		procBVLen:   dll.NewProc(PROCNAME_BV_LEN),
+		procBVWrite: dll.NewProc(PROCNAME_BV_WRITE),
+		procBVRead:  dll.NewProc(PROCNAME_BV_READ),
+
+		procPCInit: dll.NewProc(PROCNAME_PC_INIT),
+		procPCCall: dll.NewProc(PROCNAME_PC_CALL),
+	}
+	return zdl, nil
+}
+
+func (l *ZRFUDyLib) SetDebugMode(b bool) {
+	if b {
+		_, _, _ = l.procDbgOn.Call()
+	} else {
+		_, _, _ = l.procDbgOff.Call()
+	}
+}
+
+func (l *ZRFUDyLib) procCall(proc *dylib.LazyProc, a ...uintptr) (uintptr, error) {
+	retval, _, _ := proc.Call(a...)
+	err := CheckRetVal(int32(retval))
+	if err != nil {
+		return 0, err
+	}
+	return retval, nil
+}

+ 61 - 0
go-zrfu/errno.go

@@ -0,0 +1,61 @@
+package go_zrfu
+
+import (
+	"fmt"
+)
+
+var errBehaviorMap map[uint32]string = map[uint32]string{
+	0x0001: "NullPointerOfHandle",
+	0x0002: "NullHandle",
+	0x0003: "InvalidHandle",
+	0x0004: "StaleVersionHandle",
+	0x0005: "HandleIndexPastEnd",
+	0x0006: "HandleMapWrong",
+	0x0007: "NullBufferPtr",
+	0x0008: "IOError",
+	0x0009: "CBORDecodeError",
+	0x000A: "ProcNotFound",
+	0x000B: "ProcRegistryNameError",
+	0x000C: "ProcCallerNotInit",
+	0x000D: "ProcCallerRepeatlyInit",
+	0x000E: "ArgsCBORDecodeError",
+	0x000F: "ReturnCBOREncodeError",
+	0x0010: "NoDataToEncodeCBOR",
+	0x0011: "NoArgsNeed",
+	0x0012: "NoReturnProvided",
+	0x0013: "CanNotGetArgs",
+}
+
+var errPrefixMap map[uint32]string = map[uint32]string{
+	0x0000_0000: "generic",
+	0x0001_0000: "BytesVec",
+	0x0002_0000: "ProcCaller",
+	0x0101_0000: "ProcCallBasic",
+	0x0102_0000: "ProcCallInput",
+	0x0103_0000: "ProcCallReturn",
+	0x0201_0000: "ProcCalling",
+}
+
+func CheckRetVal(retcode int32) error {
+	if retcode >= 0 {
+		return nil
+	}
+	ecode := uint32(-retcode)
+	beh := ecode & 0x0000FFFF
+	prefix := ecode & 0xFFFF0000
+	v1, ok := errPrefixMap[prefix]
+	var ps string
+	if ok {
+		ps = v1
+	} else {
+		ps = "Unknown"
+	}
+	var bhs string
+	v2, ok := errBehaviorMap[beh]
+	if ok {
+		bhs = v2
+	} else {
+		bhs = "Unknown"
+	}
+	return fmt.Errorf("zrfu calling error: %s.%s", ps, bhs)
+}

+ 10 - 0
go-zrfu/go.mod

@@ -0,0 +1,10 @@
+module git.swzry.com/zry/zry-rust-ffi-utils/go-zrfu
+
+go 1.19
+
+require (
+	github.com/fxamacker/cbor/v2 v2.4.0
+	github.com/ying32/dylib v0.0.0-20220227124818-fdf9ea9fbc96
+)
+
+require github.com/x448/float16 v0.8.4 // indirect

+ 6 - 0
go-zrfu/go.sum

@@ -0,0 +1,6 @@
+github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
+github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/ying32/dylib v0.0.0-20220227124818-fdf9ea9fbc96 h1:+kU/yXSAQPL4G7OQOxz/j62GdM+G5yd5J1/NNm7u3QI=
+github.com/ying32/dylib v0.0.0-20220227124818-fdf9ea9fbc96/go.mod h1:WPBTfbqg/aA1xqHFPB4fgBHETq/G/75yErbnexmaEOo=

+ 6 - 0
go.work

@@ -0,0 +1,6 @@
+go 1.19
+
+use (
+	go-zrfu
+	example/go
+)

+ 88 - 0
zrfu-macro/Cargo.lock

@@ -0,0 +1,88 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "zrfu-macro"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]

+ 13 - 0
zrfu-macro/Cargo.toml

@@ -0,0 +1,13 @@
+[package]
+name = "zrfu-macro"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+syn = { version="2.0.16", features=["full"] }
+quote = "1.0.27"
+proc-macro2 = "1.0.58"
+proc-macro-error = "1.0.4"

+ 343 - 0
zrfu-macro/src/lib.rs

@@ -0,0 +1,343 @@
+use proc_macro::TokenStream;
+use std::fmt::format;
+use quote::{quote, quote_spanned, TokenStreamExt, ToTokens};
+use syn::parse::{Parse, ParseStream, Result};
+use syn::spanned::Spanned;
+use syn::{token, parse_macro_input, Ident, Token, Type, Stmt, Block, Error};
+use syn::token::RArrow;
+use proc_macro_error::{proc_macro_error, abort};
+
+#[macro_use]
+extern crate syn;
+
+const fmt_tip:&str = "`proc fn ProcName (Arg: ArgType) -> (Ret: RetType) { ... }`";
+
+struct ArgDef {
+    name: Ident,
+    colon_token: token::Colon,
+    type_name: Type,
+}
+
+struct FnDef {
+    name: Ident,
+    args: Option<ArgDef>,
+    ret: Option<ArgDef>,
+    fn_body: Block,
+}
+
+impl Parse for ArgDef {
+    fn parse(input: ParseStream) -> Result<Self> {
+        Ok(ArgDef{
+            name: input.parse()?,
+            colon_token: input.parse()?,
+            type_name: input.parse()?,
+        })
+    }
+}
+
+impl Parse for FnDef {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let start_token_res = input.parse::<Ident>();
+        let start_token = match start_token_res {
+            Err(e) => {
+                abort! { input.span(),
+                    "expect 'proc'";
+                    note = "expect 'proc' here, but not found.";
+                    help = fmt_tip;
+                }
+            },
+            Ok(id) => id,
+        };
+        if start_token != "proc" {
+            abort! { start_token.span(),
+                    "expect 'proc'";
+                    note = format!("expect 'proc' here, but found '{}'", start_token);
+                    help = fmt_tip;
+                }
+        }
+        let fn_token_res = input.parse::<Token![fn]>();
+        match fn_token_res {
+            Err(e) => {
+                abort! { input.span(),
+                    "expect 'fn'";
+                    note = "expect 'fn' here, but not found.";
+                    help = fmt_tip;
+                }
+            },
+            Ok(_) => (),
+        };
+        let fn_name_res = input.parse::<Ident>();
+        let fn_name = match fn_name_res {
+            Err(e) => {
+                abort! { input.span(),
+                    "expect proc name";
+                    note = "expect an ident here, but not found.";
+                    help = fmt_tip;
+                }
+            },
+            Ok(id) => id,
+        };
+        let args_pat_inner;
+        parenthesized!(args_pat_inner in input);
+        let args = if args_pat_inner.is_empty() {
+            None
+        }else{
+            let args_parse_res = args_pat_inner.parse::<ArgDef>();
+            match args_parse_res {
+                Err(e) => {
+                    abort! { input.span(),
+                        "expect args define or nothing";
+                        note = "expect args define or nothing";
+                        help = fmt_tip;
+                    }
+                },
+                Ok(t) => Option::Some(t),
+            }
+        };
+        let ra_res = input.parse::<token::RArrow>();
+        match ra_res {
+            Err(e) => {
+                abort! { input.span(),
+                        "expect '->'";
+                        note = "expect '->' here";
+                        help = fmt_tip;
+                    }
+            },
+            Ok(t) => Option::Some(t),
+        };
+        let ret_pat_inner;
+        parenthesized!(ret_pat_inner in input);
+        let ret = if ret_pat_inner.is_empty(){
+            None
+        }else{
+            let ret_parse_res = ret_pat_inner.parse::<ArgDef>();
+            match ret_parse_res {
+                Err(e) => {
+                    abort! { input.span(),
+                        "expect ret define or nothing";
+                        note = "expect ret define or nothing";
+                        help = fmt_tip;
+                    }
+                },
+                Ok(t) => Option::Some(t),
+            }
+        };
+        let fn_body_res = input.parse::<Block>();
+        let fn_body = match fn_body_res {
+            Err(e) => {
+                abort! { input.span(),
+                    "expect function body here";
+                    note = "expect function body here, but not found.";
+                    help = fmt_tip;
+                }
+            },
+            Ok(t) => t,
+        };
+        Ok(FnDef{
+            name: fn_name,
+            args: args,
+            ret: ret,
+            fn_body: fn_body,
+        })
+    }
+}
+
+
+/// Usage:
+///
+///     zrfu_proc_def! {
+///         proc fn $PROC_NAME ( $ARGS_NAME: $ARGS_TYPE ) -> ( $RET_NAME: $RET_TYPE ) {
+///
+///         }
+///     }
+///
+/// For example:
+///
+///     zrfu_proc_def! {
+///         proc fn TestProcAR ( in: Type1 ) -> ( out: Type2 ) {
+///             // ...
+///         }
+///     }
+///
+///     zrfu_proc_def! {
+///         proc fn TestProcN () -> () {
+///             // ...
+///         }
+///     }
+///
+///     zrfu_proc_def! {
+///         proc fn TestProcA ( in: Type1 ) -> () {
+///             // ...
+///         }
+///     }
+///
+///     zrfu_proc_def! {
+///         proc fn TestProcR () -> ( out: Type2 ) {
+///             // ...
+///         }
+///     }
+///
+
+#[proc_macro]
+#[proc_macro_error]
+pub fn zrfu_proc_def(input: TokenStream) -> TokenStream {
+    let ast = parse_macro_input!(input as FnDef);
+    let tk_proc_name = ast.name;
+    let mut tk_strm_blk = proc_macro2::TokenStream::new();
+    tk_strm_blk.append_all(ast.fn_body.stmts);
+    let tk_stmts = tk_strm_blk;
+    let tk_fields = match &ast.args {
+        None => {
+            match &ast.ret {
+                None => {
+                    quote!{
+                        proc_name: String,
+                    }
+                },
+                Some(ret) => {
+                    let tk_ret_type = ret.type_name.clone();
+                    quote!{
+                        proc_name: String,
+                        ret: ZRFUProcReturn<#tk_ret_type>,
+                    }
+                },
+            }
+        },
+        Some(arg) => {
+            match &ast.ret {
+                None => {
+                    let tk_args_type = arg.type_name.clone();
+                    quote!{
+                        proc_name: String,
+                        args: ZRFUProcArgs<#tk_args_type>,
+                    }
+                },
+                Some(ret) => {
+                    let tk_ret_type = ret.type_name.clone();
+                    let tk_args_type = arg.type_name.clone();
+                    quote!{
+                        proc_name: String,
+                        ret: ZRFUProcReturn<#tk_ret_type>,
+                        args: ZRFUProcArgs<#tk_args_type>,
+                    }
+                },
+            }
+        },
+    };
+    let tk_decode_input = match &ast.args {
+        None => {
+            quote!{
+                ZRFUProcResultCode::NoArgsNeed
+            }
+        },
+        Some(_) => {
+            quote!{
+                self.args.cbor_deserialize(bv)
+            }
+        },
+    };
+    let tk_encode_return = match &ast.ret {
+        None => {
+            quote!{
+                ZRFUProcResultCode::NoReturnProvided
+            }
+        },
+        Some(_) => {
+            quote!{
+                self.ret.cbor_serialize(bv)
+            }
+        },
+    };
+    let tk_process_input = match &ast.args {
+        None => {
+            quote!{
+            }
+        },
+        Some(arg) => {
+            let tk_argname = arg.name.clone();
+            quote!{
+                let #tk_argname = match self.args.get_data() {
+                    None => { return ZRFUProcResultCode::CanNotGetArgs; },
+                    Some(t) => t,
+                };
+            }
+        },
+    };
+    let tk_process_return = match &ast.ret {
+        None => {
+            quote!{
+            }
+        },
+        Some(ret) => {
+            let tk_retname = ret.name.clone();
+            quote!{
+                self.ret.set_data(#tk_retname);
+            }
+        },
+    };
+    let tk_new_inst = match &ast.args {
+        None => {
+            match &ast.ret {
+                None => {
+                    quote!{
+                        proc_name: name,
+                    }
+                },
+                Some(_) => {
+                    quote!{
+                        proc_name: name,
+                        ret: ZRFUProcReturn::new(),
+                    }
+                },
+            }
+        },
+        Some(_) => {
+            match &ast.ret {
+                None => {
+                    quote!{
+                        proc_name: name,
+                        args: ZRFUProcArgs::new(),
+                    }
+                },
+                Some(ret) => {
+                    quote!{
+                        proc_name: name,
+                        ret: ZRFUProcReturn::new(),
+                        args: ZRFUProcArgs::new(),
+                    }
+                },
+            }
+        },
+    };
+    let expanded = quote!{
+        pub struct #tk_proc_name {
+            #tk_fields
+        }
+
+        impl ZRFUProcInstanceTrait for #tk_proc_name {
+            fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                #tk_decode_input
+            }
+
+            fn call(&mut self) -> ZRFUProcResultCode {
+                #tk_process_input
+                #tk_stmts
+                #tk_process_return
+                return ZRFUProcResultCode::Ok;
+            }
+
+            fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                #tk_encode_return
+            }
+        }
+
+        impl #tk_proc_name {
+            fn factory(name: String) -> Box<dyn ZRFUProcInstanceTrait> {
+                Box::new(#tk_proc_name{
+                    #tk_new_inst
+                })
+            }
+        }
+    };
+    TokenStream::from(expanded)
+}

+ 320 - 0
zry-rust-ffi-utils/Cargo.lock

@@ -0,0 +1,320 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bytebuffer"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce2468af960a9069ae7f77b6c16836e0ccc13f0caf8c8856b942924241c72f7b"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "ciborium"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "concurrent-hashmap"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b497d3441e4e31ef52273f344aacf0a24d28a353837451a45df9b3e9cf7d44a"
+dependencies = [
+ "spin",
+]
+
+[[package]]
+name = "cstr"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aa998c33a6d3271e3678950a22134cd7dd27cef86dee1b611b5b14207d1d90b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "ffi-support"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27838c6815cfe9de2d3aeb145ffd19e565f577414b33f3bdbf42fe040e9e0ff6"
+dependencies = [
+ "lazy_static",
+ "log",
+]
+
+[[package]]
+name = "half"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.144"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "num_enum"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+
+[[package]]
+name = "serde"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "spin"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14db77c5b914df6d6173dda9a3b3f5937bd802934fa5edaf934df06a3491e56f"
+
+[[package]]
+name = "strum"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
+
+[[package]]
+name = "strum_macros"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f"
+
+[[package]]
+name = "toml_edit"
+version = "0.19.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92d964908cec0d030b812013af25a0e57fddfadb1e066ecc6681d86253129d4f"
+dependencies = [
+ "indexmap",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+
+[[package]]
+name = "winnow"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "zry-rust-ffi-utils"
+version = "0.1.0"
+dependencies = [
+ "bytebuffer",
+ "ciborium",
+ "ciborium-io",
+ "concurrent-hashmap",
+ "cstr",
+ "ffi-support",
+ "lazy_static",
+ "libc",
+ "num_enum",
+ "once_cell",
+ "serde",
+ "strum",
+ "strum_macros",
+]

+ 24 - 0
zry-rust-ffi-utils/Cargo.toml

@@ -0,0 +1,24 @@
+[package]
+name = "zry-rust-ffi-utils"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+libc = "*"
+ffi-support = "0.4.0"
+lazy_static = "1.4.0"
+num_enum = "0.6.1"
+strum = "0.24.1"
+strum_macros = "0.24.3"
+bytebuffer = "2.1.1"
+cstr = "0.2.11"
+ciborium = "0.2.1"
+serde = { version = "1.0", features = ["derive"] }
+ciborium-io = "0.2.1"
+once_cell = "1.17.1"
+
+[dependencies.concurrent-hashmap]
+version = "0.2.2"
+default-features = false

+ 205 - 0
zry-rust-ffi-utils/src/bytes_vec/mod.rs

@@ -0,0 +1,205 @@
+use core::slice;
+use std::sync::atomic::{Ordering};
+use std::{io};
+use std::io::Write;
+use ffi_support::{ConcurrentHandleMap, IntoFfi};
+use lazy_static::lazy_static;
+use libc::*;
+use crate::errno::{ZRFUErrBehavior, ZRFUErrNo, ZRFUErrPrefix};
+use crate::get_handle_from_ptr;
+use bytebuffer::ByteBuffer;
+
+pub struct ZRFUBytesVec {
+    buf: ByteBuffer,
+}
+
+lazy_static! {
+    static ref BYTES_VEC_MM: ConcurrentHandleMap<ZRFUBytesVec> = ConcurrentHandleMap::new();
+}
+
+impl ZRFUBytesVec {
+    pub fn empty() -> ZRFUBytesVec {
+        ZRFUBytesVec {
+            buf: ByteBuffer::new(),
+        }
+    }
+
+    pub fn push_mm(obj : ZRFUBytesVec) -> u64 {
+        BYTES_VEC_MM.insert(obj).into_ffi_value()
+    }
+
+    pub fn do_with_object<F, R, E>(h: u64, callback: F) -> Result<R, ZRFUErrBehavior>
+        where
+            F: FnOnce(&ZRFUBytesVec) -> Result<R, ZRFUErrBehavior>,
+    {
+        BYTES_VEC_MM.get_u64(h, |bv| {
+            callback(bv)
+        })
+    }
+
+    pub fn do_with_mut_object<F, R>(h: u64, callback: F) -> Result<R, ZRFUErrBehavior>
+        where
+            F: FnOnce(&mut ZRFUBytesVec) -> Result<R, ZRFUErrBehavior>,
+    {
+        BYTES_VEC_MM.get_mut_u64(h, |bv| {
+            callback(bv)
+        })
+    }
+
+    pub fn get_usage() -> i32 {
+        BYTES_VEC_MM.len() as i32
+    }
+
+    pub fn write_u8_slice(&mut self, dat: &[u8]) -> Result<usize, io::Error> {
+        self.buf.write(dat)
+    }
+
+    pub fn read_bytes(&mut self, len: usize) -> Result<Vec<u8>, io::Error> {
+        let total_len = self.buf.len();
+        let rpos = self.buf.get_rpos();
+        let remain = total_len - rpos;
+        if remain <= 0 {
+            return Result::Ok(Vec::new());
+        }
+        let clen = if len > remain {
+            remain
+        }else{
+            len
+        };
+        self.buf.read_bytes(clen)
+    }
+
+    pub fn reset_cursors(&mut self) -> () {
+        self.buf.reset_cursors();
+    }
+
+}
+
+impl ciborium_io::Read for &mut ZRFUBytesVec{
+    type Error = std::io::Error;
+
+    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), std::io::Error> {
+        let res = <ByteBuffer as io::Read>::read_exact(&mut self.buf, buf);
+        res
+    }
+}
+
+impl ciborium_io::Write for &mut ZRFUBytesVec{
+    type Error = std::io::Error;
+
+    fn write_all(&mut self, dat: &[u8]) -> Result<(), <Self as ciborium_io::Write>::Error> {
+        let res = <ByteBuffer as io::Write>::write_all(&mut self.buf,dat);
+        res
+    }
+
+    fn flush(&mut self) -> Result<(), <Self as ciborium_io::Write>::Error> {
+        let res = <ByteBuffer as io::Write>::flush(&mut self.buf);
+        res
+    }
+}
+
+#[no_mangle]
+pub extern fn ZRFU_Debug_On() -> () {
+    crate::errno::DEBUG_MODE.store(true, Ordering::Relaxed);
+}
+
+#[no_mangle]
+pub extern fn ZRFU_Debug_Off() -> () {
+    crate::errno::DEBUG_MODE.store(false, Ordering::Relaxed);
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_New(hptr: *mut u64) -> c_int {
+    if hptr.is_null() {
+        return ZRFUErrNo::Generic_NullPointerBufferPtr.get_return_code()
+    }
+    let b = ZRFUBytesVec::empty();
+    let hdl = BYTES_VEC_MM.insert(b);
+    let h = hdl.into_ffi_value();
+    unsafe { hptr.write(h) };
+    0
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_Del(hptr : *const u64) -> c_int {
+    get_handle_from_ptr!(hptr as h);
+    let result = BYTES_VEC_MM.delete_u64(h);
+    match result {
+        Ok(_) => 0,
+        Err(e) => ZRFUErrBehavior::from(e).to_errno(ZRFUErrPrefix::BytesVec).get_return_code(),
+    }
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_Len(hptr : *const u64) -> c_int {
+    get_handle_from_ptr!(hptr as h);
+    let result:Result<usize, ZRFUErrBehavior> = BYTES_VEC_MM.get_u64(h, |bv| {
+        Result::Ok(bv.buf.len())
+    });
+    match result {
+        Ok(sz) => sz as c_int,
+        Err(err) => err.to_errno(ZRFUErrPrefix::BytesVec).get_return_code(),
+    }
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_MMUsage() -> c_int {
+    ZRFUBytesVec::get_usage()
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_Write(hptr: *const u64, ptr: *const c_uchar, len: usize) -> c_int {
+    get_handle_from_ptr!(hptr as h);
+    if len == 0 {
+        return 0
+    }
+    if ptr.is_null() {
+        return ZRFUErrNo::BytesVec_NullPointerBufferPtr.get_return_code()
+    }
+    let result = BYTES_VEC_MM.get_mut_u64(h, |bv| {
+        let b = unsafe{ slice::from_raw_parts(ptr, len) };
+        let res = bv.write_u8_slice(b);
+        match res {
+            Ok(sz) => Result::Ok(sz),
+            Err(err) => Result::Err(ZRFUErrBehavior::IOError
+                .with_complex_error(format!("ByteVec IO Error: {}", err.to_string()).as_str()))
+        }
+    });
+    match result {
+       Ok(sz) => sz as c_int,
+        Err(err) => err.to_errno(ZRFUErrPrefix::BytesVec).get_return_code(),
+    }
+}
+
+#[no_mangle]
+pub extern fn ZRFU_BytesVec_Read(hptr: *const u64, ptr: *mut c_uchar, len: usize) -> c_int {
+    get_handle_from_ptr!(hptr as h);
+    if len == 0 {
+        return 0
+    }
+    if ptr.is_null() {
+        return ZRFUErrNo::BytesVec_NullPointerBufferPtr.get_return_code()
+    }
+    let result = BYTES_VEC_MM.get_mut_u64(h, |bv| {
+        let res = bv.read_bytes(len);
+        match res {
+            Ok(dat) => {
+                let clen = if dat.len() > len {
+                    len
+                }else {
+                    dat.len()
+                };
+                unsafe {
+                    ptr.copy_from(dat.as_ptr(), clen);
+                }
+                Result::Ok(clen)
+            },
+            Err(err) => Result::Err(ZRFUErrBehavior::IOError
+                .with_complex_error(format!("ByteVec IO Error: {}", err.to_string()).as_str()))
+        }
+    });
+    match result {
+        Ok(sz) => sz as c_int,
+        Err(err) => err.to_errno(ZRFUErrPrefix::BytesVec).get_return_code(),
+    }
+}

+ 161 - 0
zry-rust-ffi-utils/src/caller/mod.rs

@@ -0,0 +1,161 @@
+use concurrent_hashmap::{ ConcHashMap };
+use libc::c_int;
+use crate::bytes_vec::ZRFUBytesVec;
+use crate::errno::{ZRFUErrBehavior, ZRFUErrNo, ZRFUErrPrefix};
+use once_cell::sync::OnceCell;
+use crate::proc::{ZRFUProcInstanceTrait, ZRFUProcResultCode};
+use std::boxed::Box;
+use ciborium::de;
+
+struct ProcCaller {
+    proc_registry: ConcHashMap<String, ProcEntity>,
+}
+
+impl ProcCaller {
+    fn new() -> Self {
+        ProcCaller{
+            proc_registry: ConcHashMap::<String, ProcEntity>::new(),
+        }
+    }
+
+    fn do_with_proc<F, R>(&self, name: &String, callback: F) -> Result<R, ZRFUErrNo>
+    where
+        F: FnOnce(&ProcEntity) -> Result<R, ZRFUErrNo>,
+    {
+        let find_res = self.proc_registry.find(name);
+        let pe = match find_res {
+            None => { return Result::Err(ZRFUErrBehavior::ProcNotFound.to_errno(ZRFUErrPrefix::ProcCallBasic)); },
+            Some(t) => {
+                t.get()
+            },
+        };
+        callback(pe)
+    }
+}
+
+pub trait  ProcCallerLibSide {
+    fn register_proc(&self, name: String, factory_func: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>);
+}
+
+impl ProcCallerLibSide for ProcCaller{
+    fn register_proc(&self, name: String, factory_func: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>) {
+        let pe = ProcEntity{
+            name: name.clone(),
+            factory: factory_func,
+        };
+        self.proc_registry.insert(name, pe);
+    }
+}
+
+struct ProcEntity {
+    name: String,
+    factory: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>,
+}
+
+static PROC_CALLER: OnceCell<ProcCaller> = OnceCell::new();
+
+extern "C" {
+    fn LibWithZRFU_Init(caller: &dyn ProcCallerLibSide);
+}
+
+#[no_mangle]
+pub extern fn ZRFU_Proc_Init() -> c_int {
+    let opc = PROC_CALLER.get();
+    match opc {
+        Some(_) => {return ZRFUErrNo::ProcCaller_ProcCallerRepeatlyInit.get_return_code(); },
+        None => (),
+    };
+    let pcls = ProcCaller::new();
+    unsafe { LibWithZRFU_Init(&pcls as &dyn ProcCallerLibSide); }
+    let _ = PROC_CALLER.set(pcls);
+    return 0;
+}
+
+#[no_mangle]
+pub extern fn ZRFU_Proc_Call(name_hptr: *const u64, in_hptr: *const u64, out_hptr: *const u64) -> c_int {
+    if name_hptr.is_null() {
+        return ZRFUErrNo::ProcCallBasic_NullPointerHandle.get_return_code();
+    }
+    let name_h = unsafe{ name_hptr.read() };
+    let name_res:Result<String, ZRFUErrBehavior> = ZRFUBytesVec::do_with_mut_object(name_h, |bv| {
+        let res = de::from_reader(bv);
+        match res {
+            Ok(t) => Result::Ok(t),
+            Err(e) => Result::Err(
+                    ZRFUErrBehavior::CBORDecodeError
+                        .with_complex_error(format!("CBOR Decode Error in ProcName Decoding: {:?}", e).as_str())
+                ),
+
+        }
+    });
+    let proc_name:String = match name_res {
+        Ok(t) => t,
+        Err(e) => {
+            return e.to_errno(ZRFUErrPrefix::ProcCallBasic).get_return_code();
+        },
+    };
+    //println!("ProcCall Test: ProcName={}", proc_name.as_str());
+    let pc_opt= PROC_CALLER.get();
+    let pc = match pc_opt {
+        None => {
+            return ZRFUErrNo::ProcCaller_ProcCallerNotInit.get_return_code();
+        },
+        Some(t) => t,
+    };
+    let proc_find_res = pc.do_with_proc(&proc_name, |pe| {
+        let has_input = !in_hptr.is_null();
+        let has_return = !out_hptr.is_null();
+        let mut proc_inst = (pe.factory)(pe.name.clone());
+        if has_input {
+            let h = unsafe{ in_hptr.read() };
+            let input_dec_res = ZRFUBytesVec::do_with_mut_object(h, |bv| {
+                let res = proc_inst.decode_input(bv);
+                if res != ZRFUProcResultCode::Ok {
+                    Result::Err(ZRFUErrBehavior::from(res))
+                }else{
+                    Result::Ok(())
+                }
+            });
+            match input_dec_res {
+                Ok(_) => (),
+                Err(e) => { return Result::Err(e.to_errno(ZRFUErrPrefix::ProcCallInput)); },
+            }
+        };
+        let call_res = proc_inst.call();
+        if call_res != ZRFUProcResultCode::Ok {
+            return Result::Err(ZRFUErrBehavior::from(call_res).to_errno(ZRFUErrPrefix::ProcCalling))
+        }
+        if has_return {
+            let h = unsafe{ out_hptr.read() };
+            let return_enc_res = ZRFUBytesVec::do_with_mut_object(h, |bv| {
+                let res = proc_inst.encode_return(bv);
+                if res != ZRFUProcResultCode::Ok {
+                    Result::Err(ZRFUErrBehavior::from(res))
+                }else{
+                    Result::Ok(())
+                }
+            });
+            match return_enc_res {
+                Ok(_) => (),
+                Err(e) => { return Result::Err(e.to_errno(ZRFUErrPrefix::ProcCallReturn)); },
+            }
+        }
+        return Result::Ok(());
+    });
+    let proc_res:c_int = match proc_find_res {
+        Err(e) => {
+            return e.get_return_code();
+        },
+        Ok(_) => 0,
+    };
+    proc_res
+    /*
+    if in_hptr.is_null() {
+        return ZRFUErrNo::ProcCallInput_NullPointerHandle.get_return_code();
+    }
+    let in_h = unsafe { in_hptr.read() };
+    let in_res = ZRFUBytesVec::do_with_object(in_h, |bv| {
+
+    });
+     */
+}

+ 9 - 0
zry-rust-ffi-utils/src/cbor/mod.rs

@@ -0,0 +1,9 @@
+use serde::{Serialize, Deserialize};
+use core::fmt::Debug;
+use ciborium::Value;
+
+#[derive(Debug, Serialize, Deserialize)]
+struct CBORDefProcCallInput {
+    name: String,
+    args: Value,
+}

+ 210 - 0
zry-rust-ffi-utils/src/errno/mod.rs

@@ -0,0 +1,210 @@
+use std::convert::Into;
+use ffi_support::HandleError;
+use std::sync::atomic::{AtomicBool, Ordering};
+use num_enum::{TryFromPrimitive, IntoPrimitive};
+use strum_macros::Display;
+use core::fmt::Debug;
+use crate::define_err_enum;
+use crate::proc::ZRFUProcResultCode;
+
+pub static DEBUG_MODE: AtomicBool = AtomicBool::new(false);
+
+
+#[derive(Debug, IntoPrimitive)]
+#[repr(u32)]
+pub enum ZRFUErrPrefix {
+    Generic = 0x00_00_0000,
+    BytesVec = 0x00_01_0000,
+    ProcCaller = 0x00_02_0000,
+    ProcCallBasic = 0x01_01_0000,
+    ProcCallInput = 0x01_02_0000,
+    ProcCallReturn = 0x01_03_0000,
+    ProcCalling = 0x0201_0000,
+}
+
+impl ZRFUErrPrefix {
+    pub const fn define(self, gtype: ZRFUErrBehavior) -> u32 {
+        unsafe {
+            let prefix = *((&self as *const ZRFUErrPrefix) as *const u32);
+            let behavior = *((&gtype as *const ZRFUErrBehavior) as *const u32);
+            prefix | behavior
+        }
+    }
+}
+
+#[derive(Debug, IntoPrimitive)]
+#[repr(u32)]
+pub enum ZRFUErrBehavior {
+    Ok = 0x0000,
+
+    NullPointerHandle = 0x0001,
+    NullHandle = 0x0002,
+    InvalidHandle = 0x0003,
+    StaleVersion = 0x0004,
+    IndexPastEnd = 0x0005,
+    WrongMap = 0x0006,
+    NullPointerBufferPtr = 0x0007,
+    IOError = 0x0008,
+    CBORDecodeError = 0x0009,
+    ProcNotFound = 0x000A,
+    ProcRegistryNameError = 0x000B,
+    ProcCallerNotInit = 0x000C,
+    ProcCallerRepeatlyInit = 0x000D,
+    ArgsCBORDecodeError = 0x000E,
+    ReturnCBOREncodeError = 0x000F,
+    NoDataToEncodeCBOR = 0x0010,
+    NoArgsNeed = 0x011,
+    NoReturnProvided = 0x0012,
+    CanNotGetArgs = 0x0013,
+}
+
+impl ZRFUErrBehavior {
+    pub fn to_errno(self, prefix: ZRFUErrPrefix) -> ZRFUErrNo {
+        let behavior: u32 = (self as ZRFUErrBehavior).into();
+        let prefu32: u32 = prefix.into();
+        let v = behavior | prefu32;
+        let res = ZRFUErrNo::try_from(v);
+        match res {
+            Ok(t) => t,
+            Err(_) => {
+                let fbv = ZRFUErrNo::try_from(behavior);
+                match fbv {
+                    Ok(t) => t,
+                    Err(_) => ZRFUErrNo::Unknown,
+                }
+            },
+        }
+    }
+
+    pub fn with_complex_error(self, err_msg: &str) -> Self {
+        let dbg = DEBUG_MODE.load(Ordering::Relaxed);
+        if dbg {
+            println!("ZRFU_Debug: Error: {}", err_msg);
+        }
+        self
+    }
+}
+
+/*#[derive(TryFromPrimitive, IntoPrimitive, Display)]
+#[repr(u32)]
+pub enum ZRFUErrNo {
+    OK = 0x00000000,
+    Unknown = 0x4000FFFF,
+
+}
+*/
+
+define_err_enum!{
+    NullPointerHandle for Generic as Generic_NullPointerHandle,
+    NullHandle for Generic as Generic_NullHandle,
+    InvalidHandle for Generic as Generic_InvalidHandle,
+    StaleVersion for Generic as Generic_StaleVersion,
+    IndexPastEnd for Generic as Generic_IndexPastEnd,
+    WrongMap for Generic as Generic_WrongMap,
+    NullPointerBufferPtr for Generic as Generic_NullPointerBufferPtr,
+    IOError for Generic as Generic_IOError,
+
+    NullPointerHandle for BytesVec as BytesVec_NullPointerHandle,
+    NullHandle for BytesVec as BytesVec_NullHandle,
+    InvalidHandle for BytesVec as BytesVec_InvalidHandle,
+    StaleVersion for BytesVec as BytesVec_StaleVersion,
+    IndexPastEnd for BytesVec as BytesVec_IndexPastEnd,
+    WrongMap for BytesVec as BytesVec_WrongMap,
+    NullPointerBufferPtr for BytesVec as BytesVec_NullPointerBufferPtr,
+    IOError for BytesVec as BytesVec_IOError,
+
+    ProcCallerNotInit for ProcCaller as ProcCaller_ProcCallerNotInit,
+    ProcCallerRepeatlyInit for ProcCaller as ProcCaller_ProcCallerRepeatlyInit,
+
+    NullPointerHandle for ProcCallBasic as ProcCallBasic_NullPointerHandle,
+    NullHandle for ProcCallBasic as ProcCallBasic_NullHandle,
+    InvalidHandle for ProcCallBasic as ProcCallBasic_InvalidHandle,
+    StaleVersion for ProcCallBasic as ProcCallBasic_StaleVersion,
+    IndexPastEnd for ProcCallBasic as ProcCallBasic_IndexPastEnd,
+    WrongMap for ProcCallBasic as ProcCallBasic_WrongMap,
+    NullPointerBufferPtr for ProcCallBasic as ProcCallBasic_NullPointerBufferPtr,
+    IOError for ProcCallBasic as ProcCallBasic_IOError,
+    CBORDecodeError for ProcCallBasic as ProcCallBasic_CBORDecodeError,
+    ProcNotFound for ProcCallBasic as ProcCallBasic_ProcNotFound,
+    ProcRegistryNameError for ProcCallBasic as ProcCallBasic_ProcRegistryNameError,
+
+    NullHandle for ProcCallInput as ProcCallInput_NullHandle,
+    InvalidHandle for ProcCallInput as ProcCallInput_InvalidHandle,
+    StaleVersion for ProcCallInput as ProcCallInput_StaleVersion,
+    IndexPastEnd for ProcCallInput as ProcCallInput_IndexPastEnd,
+    WrongMap for ProcCallInput as ProcCallInput_WrongMap,
+    NullPointerBufferPtr for ProcCallInput as ProcCallInput_NullPointerBufferPtr,
+    IOError for ProcCallInput as ProcCallInput_IOError,
+    ArgsCBORDecodeError for ProcCallInput as ProcCallInput_ArgsCBORDecodeError,
+
+    NullHandle for ProcCallReturn as ProcCallReturn_NullHandle,
+    InvalidHandle for ProcCallReturn as ProcCallReturn_InvalidHandle,
+    StaleVersion for ProcCallReturn as ProcCallReturn_StaleVersion,
+    IndexPastEnd for ProcCallReturn as ProcCallReturn_IndexPastEnd,
+    WrongMap for ProcCallReturn as ProcCallReturn_WrongMap,
+    NullPointerBufferPtr for ProcCallReturn as ProcCallReturn_NullPointerBufferPtr,
+    IOError for ProcCallReturn as ProcCallReturn_IOError,
+    ReturnCBOREncodeError for ProcCallReturn as ProcCallReturn_ReturnCBOREncodeError,
+    NoDataToEncodeCBOR for ProcCallReturn as ProcCallReturn_NoDataToEncodeCBOR,
+
+    NoArgsNeed for ProcCalling as ProcCalling_NoArgsNeed,
+    NoReturnProvided for ProcCalling as ProcCalling_NoReturnProvided,
+    CanNotGetArgs for ProcCalling as ProcCalling_CanNotGetArgs
+}
+
+impl ZRFUErrNo {
+    pub fn get_errno(self) -> u32 {
+        (self as ZRFUErrNo).into()
+    }
+    pub fn get_return_code(self) -> i32 {
+        let ec : u32 = (self as ZRFUErrNo).into();
+        -(ec as i32)
+    }
+    pub fn from_return_code(v : i32) -> ZRFUErrNo {
+        if v < 0 {
+            let res = ZRFUErrNo::try_from((-v) as u32);
+            match res {
+                Ok(n) => n,
+                Err(_) => ZRFUErrNo::Unknown,
+            }
+        }else{
+            ZRFUErrNo::OK
+        }
+    }
+
+    pub fn with_complex_error(self, err_msg: &str) -> Self {
+        let dbg = DEBUG_MODE.load(Ordering::Relaxed);
+        if dbg {
+            println!("ZRFU_Debug: Error: {}", err_msg);
+        }
+        self
+    }
+}
+
+impl From<HandleError> for ZRFUErrBehavior {
+    fn from(he: HandleError) -> Self {
+        match he {
+            HandleError::NullHandle => Self::NullHandle,
+            HandleError::InvalidHandle => Self::InvalidHandle,
+            HandleError::StaleVersion => Self::StaleVersion,
+            HandleError::IndexPastEnd => Self::IndexPastEnd,
+            HandleError::WrongMap => Self::WrongMap,
+        }
+    }
+}
+
+impl From<ZRFUProcResultCode> for ZRFUErrBehavior {
+    fn from(value: ZRFUProcResultCode) -> Self {
+        match value {
+            ZRFUProcResultCode::Ok => ZRFUErrBehavior::Ok,
+            ZRFUProcResultCode::NoArgsNeed => ZRFUErrBehavior::NoArgsNeed,
+            ZRFUProcResultCode::NoReturnProvided => ZRFUErrBehavior::NoReturnProvided,
+            ZRFUProcResultCode::ArgsCBORDecodeError(s) => ZRFUErrBehavior::ArgsCBORDecodeError
+                .with_complex_error(s.as_str()),
+            ZRFUProcResultCode::CanNotGetArgs => ZRFUErrBehavior::CanNotGetArgs,
+            ZRFUProcResultCode::ReturnCBOREncodeError(s) => ZRFUErrBehavior::ReturnCBOREncodeError
+                .with_complex_error(s.as_str()),
+            ZRFUProcResultCode::NoDataToEncodeCBOR => ZRFUErrBehavior::NoDataToEncodeCBOR,
+        }
+    }
+}

+ 8 - 0
zry-rust-ffi-utils/src/lib.rs

@@ -0,0 +1,8 @@
+extern crate core;
+
+pub mod bytes_vec;
+pub mod errno;
+pub mod macros;
+pub mod proc;
+pub mod caller;
+pub mod cbor;

+ 172 - 0
zry-rust-ffi-utils/src/macros/mod.rs

@@ -0,0 +1,172 @@
+#[macro_export]
+macro_rules! get_handle_from_ptr {
+    ($hptr:ident as $hval:ident) => {
+        if $hptr.is_null() {
+            return ZRFUErrNo::Generic_NullPointerHandle.get_return_code()
+        };
+        let $hval = unsafe { $hptr.read() };
+    }
+}
+
+#[macro_export]
+macro_rules! define_err_enum {
+    ($( $behv:ident for $prefix:ident as $name:ident ), * ) => {
+        #[allow(non_camel_case_types)]
+        #[derive(Debug, TryFromPrimitive, IntoPrimitive, Display)]
+        #[repr(u32)]
+        pub enum ZRFUErrNo {
+            OK = 0x00000000,
+            Unknown = 0x4000FFFF,
+            $(
+                $name = ZRFUErrPrefix::$prefix.define(ZRFUErrBehavior::$behv),
+            )*
+        }
+
+    }
+}
+
+#[macro_export]
+macro_rules! proc_def_ar {
+    ( $proc_name:ident ($args_type:ty as $argname:ident ; $ret_type:ty as $retname:ident)  $code:block  ) => {
+        pub struct $proc_name {
+            proc_name: String,
+            args: ZRFUProcArgs<$args_type>,
+            ret: ZRFUProcReturn<$ret_type>,
+        }
+
+        impl ZRFUProcInstanceTrait for $proc_name {
+            fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                self.args.cbor_deserialize(bv)
+            }
+
+            fn call(&mut self) -> ZRFUProcResultCode {
+                let $argname = match self.args.get_data() {
+                    None => { return ZRFUProcResultCode::CanNotGetArgs; },
+                    Some(t) => t,
+                };
+                $code;
+                self.ret.set_data($retname);
+                return ZRFUProcResultCode::Ok;
+            }
+
+            fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                self.ret.cbor_serialize(bv)
+            }
+        }
+
+        impl $proc_name {
+            fn factory(name: String) -> Box<dyn ZRFUProcInstanceTrait> {
+                Box::new($proc_name{
+                    proc_name: name,
+                    args: ZRFUProcArgs::new(),
+                    ret: ZRFUProcReturn::new(),
+                })
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! proc_def_a {
+    ( $proc_name:ident ($args_type:ty as $argname:ident)  $code:block  ) => {
+        pub struct $proc_name {
+            proc_name: String,
+            args: ZRFUProcArgs<$args_type>,
+        }
+
+        impl ZRFUProcInstanceTrait for $proc_name {
+            fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                self.args.cbor_deserialize(bv)
+            }
+
+            fn call(&mut self) -> ZRFUProcResultCode {
+                let $argname = match self.args.get_data() {
+                    None => { return ZRFUProcResultCode::CanNotGetArgs; },
+                    Some(t) => t,
+                };
+                $code;
+                return ZRFUProcResultCode::Ok;
+            }
+
+            fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                ZRFUProcResultCode::NoReturnProvided
+            }
+        }
+
+        impl $proc_name {
+            fn factory(name: String) -> Box<dyn ZRFUProcInstanceTrait> {
+                Box::new($proc_name{
+                    proc_name: name,
+                    args: ZRFUProcArgs::new(),
+                })
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! proc_def_r {
+    ( $proc_name:ident ($ret_type:ty as $retname:ident)  $code:block  ) => {
+        pub struct $proc_name {
+            proc_name: String,
+            ret: ZRFUProcReturn<$ret_type>,
+        }
+
+        impl ZRFUProcInstanceTrait for $proc_name {
+            fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                ZRFUProcResultCode::NoArgsNeed
+            }
+
+            fn call(&mut self) -> ZRFUProcResultCode {
+                $code;
+                self.ret.set_data($retname);
+                return ZRFUProcResultCode::Ok;
+            }
+
+            fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                self.ret.cbor_serialize(bv)
+            }
+        }
+
+        impl $proc_name {
+            fn factory(name: String) -> Box<dyn ZRFUProcInstanceTrait> {
+                Box::new($proc_name{
+                    proc_name: name,
+                    ret: ZRFUProcReturn::new(),
+                })
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! proc_def_n {
+    ( $proc_name:ident ()  $code:block  ) => {
+        pub struct $proc_name {
+            proc_name: String,
+        }
+
+        impl ZRFUProcInstanceTrait for $proc_name {
+            fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                ZRFUProcResultCode::NoArgsNeed
+            }
+
+            fn call(&mut self) -> ZRFUProcResultCode {
+                $code;
+                return ZRFUProcResultCode::Ok;
+            }
+
+            fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+                ZRFUProcResultCode::NoReturnProvided
+            }
+        }
+
+        impl $proc_name {
+            fn factory(name: String) -> Box<dyn ZRFUProcInstanceTrait> {
+                Box::new($proc_name{
+                    proc_name: name,
+                })
+            }
+        }
+    };
+}

+ 89 - 0
zry-rust-ffi-utils/src/proc/mod.rs

@@ -0,0 +1,89 @@
+use crate::bytes_vec::ZRFUBytesVec;
+use ciborium::de;
+use ciborium::ser;
+use once_cell::sync::OnceCell;
+use serde::de::DeserializeOwned;
+use serde::Serialize;
+
+pub trait ZRFUProcInstanceTrait {
+    fn decode_input(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode;
+    fn call(&mut self) -> ZRFUProcResultCode;
+    fn encode_return(&mut self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode;
+}
+
+#[derive(Debug, PartialEq)]
+pub enum ZRFUProcResultCode {
+    Ok,
+    NoArgsNeed,
+    NoReturnProvided,
+    ArgsCBORDecodeError(String),
+    CanNotGetArgs,
+    ReturnCBOREncodeError(String),
+    NoDataToEncodeCBOR,
+}
+
+pub struct ZRFUProcArgs<T>
+    where T: DeserializeOwned
+{
+    data: OnceCell<T>,
+}
+
+impl<T: DeserializeOwned> ZRFUProcArgs<T> {
+    pub fn new() -> ZRFUProcArgs<T> {
+        return ZRFUProcArgs{
+            data: OnceCell::new(),
+        };
+    }
+
+    pub fn cbor_deserialize(&self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+        let res = de::from_reader(bv);
+        let val:T = match res {
+            Ok(t) => t,
+            Err(e) => {
+               return  ZRFUProcResultCode::ArgsCBORDecodeError(format!("CBOR Decode Error: {}", e.to_string()));
+            },
+        };
+        let _ = self.data.set(val);
+        return  ZRFUProcResultCode::Ok;
+    }
+
+    pub fn get_data(&self) -> Option<&T> {
+        self.data.get()
+    }
+}
+
+pub struct ZRFUProcReturn<T>
+    where T: Serialize
+{
+    data: OnceCell<T>,
+}
+
+impl<T: Serialize> ZRFUProcReturn<T>{
+    pub fn new() -> ZRFUProcReturn<T> {
+        return ZRFUProcReturn{
+            data: OnceCell::new(),
+        };
+    }
+
+    pub fn set_data(&self, v: T) {
+        let _ = self.data.set(v);
+    }
+
+    pub fn cbor_serialize(&self, bv: &mut ZRFUBytesVec) -> ZRFUProcResultCode {
+        let v_res = self.data.get();
+        let v = match v_res {
+            None => {
+                return ZRFUProcResultCode::NoDataToEncodeCBOR;
+            },
+            Some(t) => t,
+        };
+        let res = ser::into_writer(v, bv);
+        match res {
+            Ok(t) => t,
+            Err(e) => {
+                return  ZRFUProcResultCode::ReturnCBOREncodeError(format!("CBOR Encode Error: {}", e.to_string()))
+            },
+        };
+        return ZRFUProcResultCode::Ok;
+    }
+}