Fortran 2008 で行くつもりでしたが、TYPE(*) を使ったので Fortran 2018 かもしれません。
ZMQ ガイドブックのイントロ紹介の通信パターン例が何通りか出来るようになりました。
例:REP-REQ パターン
REQuest - REPly と名称上の類似を取っていて、意味的には対称性が悪いように思います。
他にも PUBlisher - SUBscriber パターンとか。
github.com
function は純粋、そうでないものは subroutine という伝統に従って、subroutine 主体にしてみました。
他の言語の書き換えを考えると、どうかとも思い、迷いましたが・・・
gfortran の final 処理中の print 文は、プログラム終了時は標準出力されないようです。しかし、ストールしないので、解放処理はちゃんとされているのではないかと思います。 finalize されていないようです。
block ... end block でくくって、ブロック内部で context や socket を宣言することで、ブロック脱出時に finalizer を呼び出すことにしました。
[追記] intel fortran だと allocatable にして、順序通りに deallocate しないとストールしていまうぅっ!!allocate - deallocate 方式にしました。
allocatable にして、deallocate してもいいのですが、使う前に allocate する必要も出てくるし~
コンストラクタを書いての代入は、また別の問題があるし~
oo_req.f90
program req
use, intrinsic :: iso_c_binding
use f08_zmq
implicit none
integer(c_int) :: ilen
character(10), target :: buffer, word
type(context_t), allocatable :: context
type(socket_t) , allocatable :: requester
allocate(context, requester)
call context%new()
call requester%new(context, ZMQ_REQ)
call requester%connect('tcp://localhost:5555')
call requester%send('Hello', 5, 0, ilen)
call requester%recv(buffer, 10, 0, ilen)
print *, trim(buffer(:ilen))
deallocate(requester)
deallocate(context)
end program req
hp8@HP8:~/f08_zmq/guidebook$ ./oo_req
World
zmq_close 0 Resource temporarily unavailable
zmq_ctx_destroy 0 Resource temporarily unavailable
hp8@HP8:~/f08_zmq/guidebook$
oo-rep.f90
program rep
use, intrinsic :: iso_c_binding
use f08_zmq
implicit none
integer :: ilen
character(10), target :: buffer
type(context_t), allocatable :: context
type(socket_t) , allocatable :: responder
allocate(context, responder)
call context%new()
call responder%new(context, ZMQ_REP)
call responder%bind('tcp://*:5555')
do
call responder%recv(buffer, 10, 0, ilen)
print *, 'Received Hello'
call sleep(1)
call responder%send('World', 5, 0, ilen)
end do
deallocate(responder)
deallocate(context)
end program rep
hp8@HP8:~/f08_zmq/guidebook$ ./oo_rep
Received Hello
Received Hello
^C
hp8@HP8:~/f08_zmq/guidebook$