J. *_*son 12 c haskell ffi unsafe-perform-io
我正在为C中的库创建一个FFI模块,它希望在其他任何东西之前调用一次非重入函数.这个调用是幂等的,但是有状态的,所以我可以在每个Haskell调用中调用它.但它很慢并且由于不可重入而可能导致冲突.
那么这是使用unsafePerformIO的合适时机吗?我可以将Bool包装在一个不安全的IORef或MVar中,通过忽略后续调用(全局隐藏IORef状态为False的调用)使这些初始化调用成为幂等的.
如果没有,这样做的正确方法是什么?
Don*_*art 11
我更喜欢初始化一次并提供不可伪造的令牌作为您初始化机器的证据.
所以你的证据是:
data Token = Token
Run Code Online (Sandbox Code Playgroud)
你抽象地导出.
然后你的初始化函数可以返回这个证据.
init :: IO Token
Run Code Online (Sandbox Code Playgroud)
现在,您需要将该证明传递给您的API:
bar :: Token -> IO Int
bar !tok = c_call_bar
Run Code Online (Sandbox Code Playgroud)
等等
现在,您可以使用monad或更高阶的初始化环境来包装这些内容,以使其更清晰,但这是基本的想法.
使用隐藏状态初始化C库的问题是,您最终要么无法并行访问库,要么在GHCi中遇到问题,混合编译和字节码,加载了两个不同版本的C库(这将失败链接器错误).