Skip to content

Commit

Permalink
Fix destroying poller and loading shared library
Browse files Browse the repository at this point in the history
  • Loading branch information
lj.moritorii@web.de committed Oct 21, 2021
1 parent 66c4f97 commit 1cfed34
Show file tree
Hide file tree
Showing 6 changed files with 397 additions and 204 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## 1.0.0-dev.5

### Fix destroying poller and loading shared library
- Rename `SocketMode` to `SocketType`
- Add some steps on how to use dartzmq on Android
- Address warnings in bindings.dart
- Fix destroying poller (use **poller instead of *poller)
- Add more class documentation
- Fix loading shared library for orher platforms
- Extend error messages
- Add more socket options


## 1.0.0-dev.4

### Fix heap corruption due to wrong usage of `malloc.allocate`
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ I have tested this on windows, which works.
Other platforms have not been tested, but should work.
If you have tested this plugin on another platform and got it to work, please share your findings and create an issue to add it to the list.

Once you installed this plugin place the shared library of `libzmq` next to your executable (for example place `libzmq-v142-mt-4_3_5.dll` in the folder `yourproject/build/windows/runner/Debug/`)
### Windows
Place a shared library of `libzmq` next to your executable (for example place `libzmq-v142-mt-4_3_5.dll` in the folder `yourproject/build/windows/runner/Debug/`)

> Note that in order for this plugin to work you will need to either get a shared library of `libzmq` or compile it yourself.
> Especially when using this on windows you need to make sure that `libzmq` is compiled using `MSVC-2019` if you are using `clang` it will not work ([more info](https://flutterforum.co/t/windows-desktop-flutter-ffi-and-loading-the-clang-library/3842))
### Android
Android has not been fully tested, but essentially you can follow [these steps](https://github.com/zeromq/libzmq/tree/master/builds/android), which will get you a `libzmq.so`. Which you need to include in your project following [these steps](https://github.com/truongsinh/flutter-ffi-samples/blob/master/packages/sqlite/docs/android.md#update-gradle-script)

## Usage

Create context
Expand Down
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class _MyHomePageState extends State<MyHomePage> {

@override
void initState() {
_socket = _context.createSocket(SocketMode.req);
_socket = _context.createSocket(SocketType.req);
_socket.connect("tcp://localhost:5566");
// _socket.connect("tcp://192.168.2.18:5566");
super.initState();
Expand Down
260 changes: 122 additions & 138 deletions lib/src/bindings.dart
Original file line number Diff line number Diff line change
@@ -1,210 +1,194 @@
// ignore_for_file: non_constant_identifier_names

import 'dart:ffi';

import 'package:ffi/ffi.dart';

part 'constants.dart';

typedef ZMQContext = Pointer<Void>;
typedef ZMQSocket = Pointer<Void>;
typedef ZMQPoller = Pointer<Void>;
typedef ZMQMessage = Pointer<Void>;
typedef ZMQPoller = Pointer<Void>;
typedef ZMQSocket = Pointer<Void>;

typedef zmq_bind_native = Int32 Function(
ZMQSocket socket, Pointer<Utf8> endpoint);
typedef zmq_bind_dart = int Function(ZMQSocket socket, Pointer<Utf8> endpoint);
class ZMQPollerEvent extends Struct {
external ZMQSocket socket;
@Int32()
external int fd;

external Pointer<Void> userData;
@Int16()
external int events;
}

class ZMQPollItem extends Struct {
external ZMQSocket socket;
@Int32()
external int fd;

@Int16()
external int events;
@Int16()
external int revents;
}

typedef zmq_connect_native = Int32 Function(
typedef ZmqBindNative = Int32 Function(
ZMQSocket socket, Pointer<Utf8> endpoint);
typedef zmq_connect_dart = int Function(
typedef ZmqBindDart = int Function(ZMQSocket socket, Pointer<Utf8> endpoint);

typedef ZmqConnectNative = Int32 Function(
ZMQSocket socket, Pointer<Utf8> endpoint);
typedef ZmqConnectDart = int Function(ZMQSocket socket, Pointer<Utf8> endpoint);

typedef zmq_errno_native = Int32 Function();
typedef zmq_errno_dart = int Function();
typedef ZmqErrnoNative = Int32 Function();
typedef ZmqErrnoDart = int Function();

typedef zmq_ctx_term_native = Int32 Function(ZMQContext context);
typedef zmq_ctx_term_dart = int Function(ZMQContext context);
typedef ZmqCtxTermNative = Int32 Function(ZMQContext context);
typedef ZmqCtxTermDart = int Function(ZMQContext context);

typedef zmq_ctx_new_native = ZMQContext Function();
typedef zmq_ctx_new_dart = ZMQContext Function();
typedef ZmqCtxNewNative = ZMQContext Function();
typedef ZmqCtxNewDart = ZMQContext Function();

// IO multiplexing
typedef zmq_poller_new_native = ZMQPoller Function();
typedef zmq_poller_new_dart = ZMQPoller Function();
typedef ZmqPollerNewNative = ZMQPoller Function();
typedef ZmqPollerNewDart = ZMQPoller Function();

typedef zmq_poller_destroy_native = Int32 Function(ZMQPoller poller);
typedef zmq_poller_destroy_dart = int Function(ZMQPoller poller);
typedef ZmqPollerDestroyNative = Int32 Function(Pointer<ZMQPoller> poller);
typedef ZmqPollerDestroyDart = int Function(Pointer<ZMQPoller> poller);

typedef zmq_poller_add_native = Int32 Function(
typedef ZmqPollerAddNative = Int32 Function(
ZMQPoller poller, ZMQSocket socket, Pointer<Void> userData, Int16 events);
typedef zmq_poller_add_dart = int Function(
typedef ZmqPollerAddDart = int Function(
ZMQPoller poller, ZMQSocket socket, Pointer<Void> userData, int events);

typedef zmq_poller_remove_native = Int32 Function(
typedef ZmqPollerRemoveNative = Int32 Function(
ZMQPoller poller, ZMQSocket sockeft);
typedef zmq_poller_remove_dart = int Function(
ZMQPoller poller, ZMQSocket socket);
typedef ZmqPollerRemoveDart = int Function(ZMQPoller poller, ZMQSocket socket);

typedef zmq_poll_native = Int32 Function(
typedef ZmqPollNative = Int32 Function(
Pointer<ZMQPollItem> items, Int32 nitems, Int64 timeout);
typedef zmq_poll_dart = int Function(
typedef ZmqPollDart = int Function(
Pointer<ZMQPollItem> items, int nitems, int timeout);

typedef zmq_poller_wait_all_native = Int32 Function(ZMQPoller poller,
typedef ZmqPollerWaitAllNative = Int32 Function(ZMQPoller poller,
Pointer<ZMQPollerEvent> events, Int32 count, Int64 timeout);
typedef zmq_poller_wait_all_dart = int Function(
typedef ZmqPollerWaitAllDart = int Function(
ZMQPoller poller, Pointer<ZMQPollerEvent> events, int count, int timeout);

// Messages
typedef zmq_msg_init_native = Int32 Function(ZMQMessage message);
typedef zmq_msg_init_dart = int Function(ZMQMessage message);
typedef ZmqMsgInitNative = Int32 Function(ZMQMessage message);
typedef ZmqMsgInitDart = int Function(ZMQMessage message);

typedef zmq_msg_size_native = IntPtr Function(ZMQMessage message);
typedef zmq_msg_size_dart = int Function(ZMQMessage message);
typedef ZmqMsgSizeNative = IntPtr Function(ZMQMessage message);
typedef ZmqMsgSizeDart = int Function(ZMQMessage message);

typedef zmq_msg_data_native = Pointer<Void> Function(ZMQMessage message);
typedef zmq_msg_data_dart = Pointer<Void> Function(ZMQMessage message);
typedef ZmqMsgDataNative = Pointer<Void> Function(ZMQMessage message);
typedef ZmqMsgDataDart = Pointer<Void> Function(ZMQMessage message);

typedef zmq_msg_recv_native = Int32 Function(
typedef ZmqMsgRecvNative = Int32 Function(
ZMQMessage msg, ZMQSocket socket, Int32 flags);
typedef zmq_msg_recv_dart = int Function(
typedef ZmqMsgRecvDart = int Function(
ZMQMessage msg, ZMQSocket socket, int flags);

typedef zmq_msg_more_native = Int32 Function(ZMQMessage message);
typedef zmq_msg_more_dart = int Function(ZMQMessage message);
typedef ZmqMsgMoreNative = Int32 Function(ZMQMessage message);
typedef ZmqMsgMoreDart = int Function(ZMQMessage message);

typedef zmq_msg_close_native = Int32 Function(ZMQMessage msg);
typedef zmq_msg_close_dart = int Function(ZMQMessage msg);
typedef ZmqMsgCloseNative = Int32 Function(ZMQMessage msg);
typedef ZmqMsgCloseDart = int Function(ZMQMessage msg);

typedef zmq_socket_native = ZMQSocket Function(ZMQContext context, Int32 type);
typedef zmq_socket_dart = ZMQSocket Function(ZMQContext context, int type);
typedef ZmqSocketNative = ZMQSocket Function(ZMQContext context, Int32 type);
typedef ZmqSocketDart = ZMQSocket Function(ZMQContext context, int type);

typedef zmq_close_native = Int32 Function(ZMQSocket socket);
typedef zmq_close_dart = int Function(ZMQSocket socket);
typedef ZmqCloseNative = Int32 Function(ZMQSocket socket);
typedef ZmqCloseDart = int Function(ZMQSocket socket);

typedef zmq_send_native = Int32 Function(
typedef ZmqSendNative = Int32 Function(
ZMQSocket socket, Pointer<Void> buffer, IntPtr size, Int32 flags);
typedef zmq_send_dart = int Function(
typedef ZmqSendDart = int Function(
ZMQSocket socket, Pointer<Void> buffer, int size, int flags);

typedef zmq_setsockopt_native = Void Function(
typedef ZmqsetsockoptNative = Void Function(
ZMQSocket socket, Int32 option, Pointer<Uint8> optval, IntPtr optvallen);
typedef zmq_setsockopt_dart = void Function(
typedef ZmqSetsockoptDart = void Function(
ZMQSocket socket, int option, Pointer<Uint8> optval, int optvallen);

// Native types
// class ZMQContext extends Struct {}

// class ZMQSocket extends Struct {/* void* */}

// class ZMQPoller extends Struct {/* void* */}

// class ZMQMessage extends Struct {
// // this struct actually has some values, but we're supposed to extract data
// // via functions, so we treat this as a typed void*
// }

class ZMQPollerEvent extends Struct {
external ZMQSocket socket;
@Int32()
external int fd;

external Pointer<Void> userData;
@Int16()
external int events;
}

class ZMQPollItem extends Struct {
external ZMQSocket socket;
@Int32()
external int fd;

@Int16()
external int events;
@Int16()
external int revents;
}

class ZMQBindings {
final DynamicLibrary library;

late final zmq_errno_dart zmq_errno;
late final ZmqErrnoDart zmq_errno;

late final zmq_bind_dart zmq_bind;
late final zmq_connect_dart zmq_connect;
late final zmq_ctx_new_dart zmq_ctx_new;
late final zmq_ctx_term_dart zmq_ctx_term;
late final zmq_socket_dart zmq_socket;
late final zmq_close_dart zmq_close;
late final ZmqBindDart zmq_bind;
late final ZmqConnectDart zmq_connect;
late final ZmqCtxNewDart zmq_ctx_new;
late final ZmqCtxTermDart zmq_ctx_term;
late final ZmqSocketDart zmq_socket;
late final ZmqCloseDart zmq_close;

late final zmq_send_dart zmq_send;
late final ZmqSendDart zmq_send;

late final zmq_poller_new_dart zmq_poller_new;
late final zmq_poller_destroy_dart zmq_poller_destroy;
late final zmq_poller_add_dart zmq_poller_add;
late final zmq_poller_remove_dart zmq_poller_remove;
late final zmq_poll_dart zmq_poll;
late final zmq_poller_wait_all_dart zmq_poller_wait_all;
late final ZmqPollerNewDart zmq_poller_new;
late final ZmqPollerDestroyDart zmq_poller_destroy;
late final ZmqPollerAddDart zmq_poller_add;
late final ZmqPollerRemoveDart zmq_poller_remove;
late final ZmqPollDart zmq_poll;
late final ZmqPollerWaitAllDart zmq_poller_wait_all;

late final zmq_msg_init_dart zmq_msg_init;
late final zmq_msg_close_dart zmq_msg_close;
late final zmq_msg_size_dart zmq_msg_size;
late final zmq_msg_data_dart zmq_msg_data;
late final zmq_msg_recv_dart zmq_msg_recv;
late final zmq_msg_more_dart zmq_msg_more;
late final ZmqMsgInitDart zmq_msg_init;
late final ZmqMsgCloseDart zmq_msg_close;
late final ZmqMsgSizeDart zmq_msg_size;
late final ZmqMsgDataDart zmq_msg_data;
late final ZmqMsgRecvDart zmq_msg_recv;
late final ZmqMsgMoreDart zmq_msg_more;

late final zmq_setsockopt_dart zmq_setsockopt;
late final ZmqSetsockoptDart zmq_setsockopt;

ZMQBindings(this.library) {
zmq_errno =
library.lookupFunction<zmq_errno_native, zmq_errno_dart>('zmq_errno');
zmq_bind =
library.lookupFunction<zmq_bind_native, zmq_bind_dart>('zmq_bind');
zmq_connect = library
.lookupFunction<zmq_connect_native, zmq_connect_dart>('zmq_connect');
zmq_ctx_new = library
.lookupFunction<zmq_ctx_new_native, zmq_ctx_new_dart>('zmq_ctx_new');
library.lookupFunction<ZmqErrnoNative, ZmqErrnoDart>('zmq_errno');
zmq_bind = library.lookupFunction<ZmqBindNative, ZmqBindDart>('zmq_bind');
zmq_connect =
library.lookupFunction<ZmqConnectNative, ZmqConnectDart>('zmq_connect');
zmq_ctx_new =
library.lookupFunction<ZmqCtxNewNative, ZmqCtxNewDart>('zmq_ctx_new');
zmq_ctx_term = library
.lookupFunction<zmq_ctx_term_native, zmq_ctx_term_dart>('zmq_ctx_term');
zmq_socket = library
.lookupFunction<zmq_socket_native, zmq_socket_dart>('zmq_socket');
.lookupFunction<ZmqCtxTermNative, ZmqCtxTermDart>('zmq_ctx_term');
zmq_socket =
library.lookupFunction<ZmqSocketNative, ZmqSocketDart>('zmq_socket');
zmq_close =
library.lookupFunction<zmq_close_native, zmq_close_dart>('zmq_close');

zmq_send =
library.lookupFunction<zmq_send_native, zmq_send_dart>('zmq_send');

zmq_poller_new =
library.lookupFunction<zmq_poller_new_native, zmq_poller_new_dart>(
'zmq_poller_new');
zmq_poller_destroy = library.lookupFunction<zmq_poller_destroy_native,
zmq_poller_destroy_dart>('zmq_poller_destroy');
zmq_poller_add =
library.lookupFunction<zmq_poller_add_native, zmq_poller_add_dart>(
'zmq_poller_add');
zmq_poller_remove = library.lookupFunction<zmq_poller_remove_native,
zmq_poller_remove_dart>('zmq_poller_remove');
zmq_poll =
library.lookupFunction<zmq_poll_native, zmq_poll_dart>('zmq_poll');
zmq_poller_wait_all = library.lookupFunction<zmq_poller_wait_all_native,
zmq_poller_wait_all_dart>('zmq_poller_wait_all');
library.lookupFunction<ZmqCloseNative, ZmqCloseDart>('zmq_close');

zmq_send = library.lookupFunction<ZmqSendNative, ZmqSendDart>('zmq_send');

zmq_poller_new = library
.lookupFunction<ZmqPollerNewNative, ZmqPollerNewDart>('zmq_poller_new');
zmq_poller_destroy =
library.lookupFunction<ZmqPollerDestroyNative, ZmqPollerDestroyDart>(
'zmq_poller_destroy');
zmq_poller_add = library
.lookupFunction<ZmqPollerAddNative, ZmqPollerAddDart>('zmq_poller_add');
zmq_poller_remove =
library.lookupFunction<ZmqPollerRemoveNative, ZmqPollerRemoveDart>(
'zmq_poller_remove');
zmq_poll = library.lookupFunction<ZmqPollNative, ZmqPollDart>('zmq_poll');
zmq_poller_wait_all =
library.lookupFunction<ZmqPollerWaitAllNative, ZmqPollerWaitAllDart>(
'zmq_poller_wait_all');

zmq_msg_init = library
.lookupFunction<zmq_msg_init_native, zmq_msg_init_dart>('zmq_msg_init');
zmq_msg_close =
library.lookupFunction<zmq_msg_close_native, zmq_msg_close_dart>(
'zmq_msg_close');
.lookupFunction<ZmqMsgInitNative, ZmqMsgInitDart>('zmq_msg_init');
zmq_msg_close = library
.lookupFunction<ZmqMsgCloseNative, ZmqMsgCloseDart>('zmq_msg_close');
zmq_msg_size = library
.lookupFunction<zmq_msg_size_native, zmq_msg_size_dart>('zmq_msg_size');
.lookupFunction<ZmqMsgSizeNative, ZmqMsgSizeDart>('zmq_msg_size');
zmq_msg_data = library
.lookupFunction<zmq_msg_data_native, zmq_msg_data_dart>('zmq_msg_data');
.lookupFunction<ZmqMsgDataNative, ZmqMsgDataDart>('zmq_msg_data');
zmq_msg_recv = library
.lookupFunction<zmq_msg_recv_native, zmq_msg_recv_dart>('zmq_msg_recv');
.lookupFunction<ZmqMsgRecvNative, ZmqMsgRecvDart>('zmq_msg_recv');
zmq_msg_more = library
.lookupFunction<zmq_msg_more_native, zmq_msg_more_dart>('zmq_msg_more');
.lookupFunction<ZmqMsgMoreNative, ZmqMsgMoreDart>('zmq_msg_more');

zmq_setsockopt =
library.lookupFunction<zmq_setsockopt_native, zmq_setsockopt_dart>(
library.lookupFunction<ZmqsetsockoptNative, ZmqSetsockoptDart>(
'zmq_setsockopt');
}
}
Loading

0 comments on commit 1cfed34

Please sign in to comment.