这是我的情况:
我想调用ffmpeg的av_free_packet函数:
// avformat.h
static inline void av_free_packet(AVPacket *pkt)
{
if (pkt && pkt->destruct)
pkt->destruct(pkt);
}
Run Code Online (Sandbox Code Playgroud)
但不幸的是static inline,这个功能是,因此并没有真正出现在链接库中.
但是,这是一个非常简单的功能,我可以在Haskell中重新实现.这就是我无法弄清楚该怎么做的事情.这是部分尝试(.hsc):
av_free_packet :: Ptr AVPacket -> IO ()
av_free_packet pkt =
when (nullPtr /= pkt) $ do
destruct <- (#peek AVPacket, destruct) pkt :: IO (FunPtr (Ptr AVPacket -> IO ()))
when (nullFunPtr /= destruct) $ funPtrToFun destruct pkt
funPtrToFun :: FunPtr a -> a
funPtrToFun = ?
Run Code Online (Sandbox Code Playgroud)
现在我可以求助于在C中实现这个函数(通过调用原始函数),但在我看来,调用函数指针应该可能以某种方式..
动态导入.
动态存根的类型必须是形式
(FunPtr ft) -> ft,其中ft可以是任何外来类型.举个例子,考虑一下
Run Code Online (Sandbox Code Playgroud)foreign import ccall "dynamic" mkFun :: FunPtr (CInt -> IO ()) -> (CInt -> IO ())存根工厂
mkFun将任何指针转换为C函数,该函数获取整数值作为其唯一参数,并且没有返回值到相应的Haskell函数中.
在您的情况下,使用情况类似于以下内容.
foreign import ccall "dynamic"
funPktToNil:: FunPtr (Ptr AVPacket -> IO ()) -> Ptr AVPacket -> IO ()
av_free_packet :: Ptr AVPacket -> IO ()
av_free_packet pkt =
when (nullPtr /= pkt) $ do
destruct <- (#peek AVPacket, destruct) pkt
when (nullFunPtr /= destruct) $ funPktToNil destruct pkt
Run Code Online (Sandbox Code Playgroud)
一个小例子来证明这个(ephemient的答案)确实有效(遵循gbacon的关注):
C:
#include <stdio.h>
typedef void funcType(int, int);
typedef funcType * pFuncType;
void printer(int a, int b) {
printf("%d %% %d\n", a, b);
}
pFuncType gimmeFunc(int dummy) {
return printer;
}
Run Code Online (Sandbox Code Playgroud)
哈斯克尔:
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.Ptr
foreign import ccall unsafe "gimmeFunc"
c_gimmeFunc :: Int -> IO (FunPtr (Int -> Int -> IO ()))
foreign import ccall "dynamic"
mkFunIntIntNil :: FunPtr (Int -> Int -> IO ()) -> Int -> Int -> IO ()
main :: IO ()
main = do
fun <- c_gimmeFunc 1
mkFunIntIntNil fun 3 5
Run Code Online (Sandbox Code Playgroud)
这对我有用 - 打印 3 % 5
| 归档时间: |
|
| 查看次数: |
1598 次 |
| 最近记录: |