10

これが私の状況です:

av_free_packetffmpeg の関数を呼び出したい:

// avformat.h
static inline void av_free_packet(AVPacket *pkt)
{
  if (pkt && pkt->destruct)
    pkt->destruct(pkt);
}

残念ながら、この関数は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 = ?

今のところ、この関数を C で実装することに頼ることができます (元の関数を呼び出すだけです)。

4

2 に答える 2

8

Haskell 98 Foreign Function Interface 1.0から、

動的インポート。

動的スタブの型はの形式(FunPtr ft) -> ftである必要があります。ここで、ftは任意の外部型である可能性があります。

例として、

foreign import ccall "dynamic"  
  mkFun :: FunPtr (CInt -> IO ()) -> (CInt -> IO ())

スタブ ファクトリmkFunは、唯一の引数として整数値を取得し、対応する Haskell 関数への戻り値を持たない C 関数へのポインターを変換します。

あなたの場合、使用法は次のようになります。

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
于 2009-06-15T21:14:05.547 に答える
7

これ(エフェミエントの答え)が実際に機能することを示す小さな例(gbaconの懸念に従う):

子:

#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;
}

ハスケル:

{-# 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

これは私にとってはうまくいきます-プリント3 % 5

于 2009-06-15T21:50:01.013 に答える