-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cbindings): adding tiny Waku Relay example in Golang #1794
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4b8ea80
Adding example of nwaku integration in Go
Ivansete-status f7e7b0b
libwaku.nim: adapting code to latest changes made in 34a926319
Ivansete-status 256ffeb
Makefile: copying libwaku.so to 'examples/golang' when it is built
Ivansete-status 7d1a871
Adding waku.go and README.md to give better insight on how to handle …
Ivansete-status File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
|
||
## Summary | ||
|
||
This is a simple example on how to integrate the `libwaku.so` library in a | ||
Golang app. | ||
|
||
[cgo](https://pkg.go.dev/cmd/cgo) is used in this example. | ||
|
||
There are comments in the file `waku.go` that are considered by the cgo itself and | ||
shouldn't be arbitrarily changed unless required. | ||
|
||
The important comments in the `waku.go` are the ones above the `import "C"` statement and | ||
above the `eventHandler` function. | ||
|
||
## libwaku.so | ||
|
||
Before running the example, make sure to properly export the LD_LIBRARY_PATH | ||
with the path that contains the target `libwaku.so` library. | ||
|
||
e.g. | ||
From the repo's root folder: | ||
```code | ||
export LD_LIBRARY_PATH=build | ||
``` | ||
|
||
In order to build the `libwaku.so`, go to the repo's root folder and | ||
invoke the next command, which will create `libwaku.so` under the `build` folder: | ||
|
||
```code | ||
make libwaku | ||
``` | ||
This will both generate the `libwaku.so` file under the `build` and | ||
the `examples/golang/` fodler. | ||
It is important to notice that there should be a `libwaku.so` at the same level as the `waku.go` file as per how `waku.go` is implemented. | ||
|
||
## libwaku.h & nimbase.h | ||
|
||
This is the header associated with the `libwaku.so`. | ||
|
||
The `libwaku.h` is auto-generated when building the `libwaku.so`. | ||
|
||
Everytime a new `libwaku.so` is built, the `libwaku.h` file gets stored in | ||
<REPO_ROOT_DIR>/nimcache/release/libwaku/libwaku.h. | ||
|
||
However, the `libwaku.h` is kept version-controlled just for commodity. | ||
It might be needed to update the `libwaku.h` header if a new function | ||
is added to the `libwaku.so` or any signature is modified. | ||
|
||
## Running the example | ||
|
||
- Open a terminal | ||
- cd <...>/nwaku/ | ||
- ```code | ||
export LD_LIBRARY_PATH=build | ||
``` | ||
- ```code | ||
go run examples/golang/waku.go | ||
``` | ||
note: `--help` can be appended to the end of the previous command to get better insight of possible params |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* Generated by Nim Compiler v1.6.11 */ | ||
#ifndef __libwaku__ | ||
#define __libwaku__ | ||
#define NIM_INTBITS 64 | ||
|
||
#include "nimbase.h" | ||
#undef LANGUAGE_C | ||
#undef MIPSEB | ||
#undef MIPSEL | ||
#undef PPC | ||
#undef R3000 | ||
#undef R4000 | ||
#undef i386 | ||
#undef linux | ||
#undef mips | ||
#undef near | ||
#undef far | ||
#undef powerpc | ||
#undef unix | ||
typedef struct ConfigNode ConfigNode; | ||
typedef struct NimStringDesc NimStringDesc; | ||
typedef struct TGenericSeq TGenericSeq; | ||
struct TGenericSeq {NI len; | ||
NI reserved; | ||
}; | ||
struct NimStringDesc { TGenericSeq Sup;NIM_CHAR data[SEQ_DECL_SIZE]; | ||
}; | ||
typedef N_CDECL_PTR(void, tyProc__5cp59bim9aJ4WupX5aVaD1Sg) (NCSTRING signal_0); | ||
N_LIB_PRIVATE N_NOCONV(void, signalHandler)(int sign); | ||
N_LIB_PRIVATE N_NIMCALL(NI, getRefcount)(void* p); | ||
N_LIB_IMPORT N_CDECL(NIM_BOOL, waku_new)(ConfigNode* config, NimStringDesc** jsonResp); | ||
N_LIB_IMPORT N_CDECL(NCSTRING, waku_version)(void); | ||
N_LIB_IMPORT N_CDECL(void, waku_set_event_callback)(tyProc__5cp59bim9aJ4WupX5aVaD1Sg callback); | ||
N_LIB_IMPORT N_CDECL(void, waku_content_topic)(NCSTRING appName, NU appVersion, NCSTRING contentTopicName, NCSTRING encoding, NimStringDesc** outContentTopic); | ||
N_LIB_IMPORT N_CDECL(void, waku_pubsub_topic)(NCSTRING topicName, NimStringDesc** outPubsubTopic); | ||
N_LIB_IMPORT N_CDECL(void, waku_default_pubsub_topic)(NimStringDesc** defPubsubTopic); | ||
N_LIB_IMPORT N_CDECL(NIM_BOOL, waku_relay_publish)(NCSTRING pubSubTopic, NCSTRING jsonWakuMessage, NI timeoutMs, NimStringDesc** jsonResp); | ||
N_LIB_IMPORT N_CDECL(void, waku_start)(void); | ||
N_LIB_IMPORT N_CDECL(void, waku_stop)(void); | ||
N_LIB_IMPORT N_CDECL(NIM_BOOL, waku_relay_subscribe)(NCSTRING pubSubTopic, NimStringDesc** jsonResp); | ||
N_LIB_IMPORT N_CDECL(NIM_BOOL, waku_relay_unsubscribe)(NCSTRING pubSubTopic, NimStringDesc** jsonResp); | ||
N_LIB_IMPORT N_CDECL(NIM_BOOL, waku_connect)(NCSTRING peerMultiAddr, NU timeoutMs, NimStringDesc** jsonResp); | ||
N_LIB_IMPORT N_CDECL(void, waku_poll)(void); | ||
N_LIB_IMPORT N_CDECL(void, NimMain)(void); | ||
#endif /* __libwaku__ */ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of defining the API in terms of nim types, it's generally better to declare it in terms of
c
types in the nim code (iecint
,cstring
etc) then import these "standard" types into the other languagesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is for the same reason as below, ie the generated Nim code is not ABI-stable this way except certain parts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comments @arnetheduck !
All of these variables get translated into
C
types thanks to thenimbase.h
header (included inlibwaku.h
.)nimbase.h
brings the next definitions:# define N_LIB_IMPORT extern
# define N_LIB_PRIVATE __attribute__((visibility("hidden")))
# define N_CDECL(rettype, name) rettype name
#define NIM_BOOL _Bool
, where_Bool
is the C99 standard representation of a boolean.typedef NI64 NI;
->typedef int64_t NI64;
-> ··· ->typedef signed long int __int64_t;
Personally, given that the
libwaku.h
file is auto-generated by the Nim compiler, I wouldn't touch it.Of course, I'm open to any other option that suits better from your point of view.
Kindly let me know if the above definitions are good enough :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but please understand: nimbase.h changes between Nim versions: if you compile this code with nim 1.6 and nim 2.0, you will not get the same result: you will get a different, incompatible, ABI: the result of this is that the consumer of the API will need to adjust as well: when they
import
the code in their code, their types will change depending on which version of Nim the code was compiled with. This is highly undesireable.The above point is why all languages tend to use C as the "lingua franca": developers have informally agreed that plain C types are good enough for this purpose, so the "pipeline" to consume something in one language from another is that one language translates its own native types to C types and the other language does the same journey in reverse.
NimStringDesc
is a good example: it's no longer part of nim 2.0: it has been replaced by a different type -NimStringDesc
,NIM_BOOL
and so on, as their names suggest, are internal implementation details of the nim compiler - they are not meant to be exposed to other languages or outside of Nim.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep in mind that exporting code from Nim is only half of the story: the code also needs to be imported on the other side.
When importing code on the other side, this is done by translating C types seen in libwaku.h to "native" types: if, between nim versions,
NIM_BOOL
changes fromint
tochar
(this is a valid change for Nim to make), theimport
into the target language also must change - there's no reason this should be necessary: the aim of a "C bindings" module is to remove this variability by explicitly using "C FFI" types that exist for this purpose on the Nim side.