こんにちは。

FFmpeg の関数を FFI を使って Haskell に移植しようと思い、まず  
output_example.c
を Haskell を使って書いていたところ、

void write_audio_frame(AVFormatContext *oc, AVStream *st)
{
     int out_size;
     AVCodecContext *c;
     AVPacket pkt;
     av_init_packet(&pkt);

     c = &st->codec;

     get_audio_frame(samples, audio_input_frame_size, c->channels);

     pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size,  
samples);

     pkt.pts= c->coded_frame->pts;
     pkt.flags |= PKT_FLAG_KEY;
     pkt.stream_index= st->index;
     pkt.data= audio_outbuf;

     /* write the compressed frame in the media file */
     if (av_write_frame(oc, &pkt) != 0) {
         fprintf(stderr, "Error while writing audio frame\n");
         exit(1);
     }
}

のような関数に遭遇したため alloca を使って AVPacket へのポインタを確保する 
よう
に以下のような関数を書いたところ、

FFmpeg.o(.text+0x44):fake: undefined reference to `av_init_packet'

というような参照エラーが出てしまうのですが、何が問題なのでしょうか?
(GHC-6.2.1、GHC-6.2.2 共に発生)
リンクするライブラリはきちんと指定しているため、他の部分の関数の参照はきち 
んと
成功します。


{-
一緒に出力される Main でないためライブラリファイルを作らなかった場合に出る 
エラー
は、以下のような通常の参照エラーです。

c:/ghc/ghc-6.2.2/libHSrts.a(Main.o)(.text+0x87):Main.c: undefined  
reference to `
__stginit_ZCMain'
c:/ghc/ghc-6.2.2/libHSrts.a(Main.o)(.text+0xa1):Main.c: undefined  
reference to `
ZCMain_main_closure'
-}


-----------------------------------------------------------------------------
-- -*- mode: haskell -*-
{-# OPTIONS -fglasgow-exts #-}

#include <avformat.h>
#include <avcodec.h>

module FFmpeg
where

import Foreign

data CAVPacket = CAVPacket {pktPts :: !(#type int64_t), pktDts :: !(#type  
int64_t),
                             pktDatas :: !(Ptr (#type uint8_t)), pktSize ::  
!Int, pktStreamIndex :: !Int,
                             pktFlags :: !Int, pktDuration :: !Int}
                             deriving (Eq,Show)

instance Storable CAVPacket where
   peek p   = do{ pts <- (#peek AVPacket, pts) p; dts <- (#peek AVPacket,  
dts) p;
                  datas <- (#peek AVPacket, data) p; size <- (#peek  
AVPacket, size) p;
                  stream_index <- (#peek AVPacket, stream_index) p; flags  
<- (#peek AVPacket, flags) p;
                  duration <- (#peek AVPacket, duration) p;
                  return $! CAVPacket pts dts datas size stream_index flags  
duration }
   poke p (CAVPacket pts dts datas size stream_index flags duration)
             = do{(#poke AVPacket, pts) p pts; (#poke AVPacket, dts) p dts;
                  (#poke AVPacket, data) p datas; (#poke AVPacket, size) p  
size;
                  (#poke AVPacket, stream_index) p stream_index ; (#poke  
AVPacket, flags) p flags;
                  (#poke AVPacket, duration) p duration}
   sizeOf _  = (#size AVPacket)
   -- alignment の値については自信なし
   alignment _ = 7


av_init_packet :: IO (Ptr CAVPacket)
av_init_packet =
     alloca $ \pkt -> do
         c_av_init_packet pkt
         return pkt


foreign import ccall unsafe "av_init_packet"
   c_av_init_packet :: Ptr CAVPacket -> IO ()
-----------------------------------------------------------------------------


また、FFmpeg が DLL でない場合に

ghc -fglasgow-exts FFmpeg.hs utils.c -I./ffmpeg-0.4.9-pre1/libavcodec  
-I./ffmpe
g-0.4.9-pre1/libavformat -L./ffmpeg-0.4.9-pre1/libavcodec  
-L./ffmpeg-0.4.9-pre1
/libavformat -lavcodec -lavformat -lHSrts

のような単純なコマンドを与えると libavformat から libacodec の関数を参照で 
きない
旨のする際に以下のようなエラーが出るのですが、(FFmpeg の元の Makefile を書 
き換え
る以外の方法で)どうやったら直せるでしょうか?


FFmpeg.o(.text+0x1398):fake: undefined reference to `av_init_packet'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(allformats.o)(.text+0xb): In  
functi
on `av_register_all':
c:/develop/ffmpeg-0.4.9-pre1/libavformat/allformats.c:30: undefined  
reference to
  `avcodec_register_all'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x105): In  
function `p
ng_read':
c:/develop/ffmpeg-0.4.9-pre1/libavformat/png.c:479: undefined reference to  
`infl
ateInit_'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x20d):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:644: undefined reference to `inflateEnd'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x753): In  
function `p
ng_write':
c:/develop/ffmpeg-0.4.9-pre1/libavformat/png.c:752: undefined reference to  
`defl
ateInit2_'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x876):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x8a4):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x8c8):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:669: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xa5c):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:699: undefined reference to `deflate'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xac8):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:849: undefined reference to `deflate'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xb0b):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xb33):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xb56):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:669: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xbb9):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xbe1):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xc37):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:870: undefined reference to `deflateEnd'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xc64):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xc8c):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xcb0):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:669: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xdd4):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:699: undefined reference to `deflate'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xe34):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xe5c):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xe80):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:669: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xf7b):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:661: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xfa9):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:666: undefined reference to `crc32'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0xfd0):c:/develop/ffmp
eg-0.4.9-pre1/libavformat/png.c:669: more undefined references to `crc32'  
follow

./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(png.o)(.text+0x1289): In  
function `
png_decode_idat':
c:/develop/ffmpeg-0.4.9-pre1/libavformat/png.c:442: undefined reference to  
`infl
ate'
./ffmpeg-0.4.9-pre1/libavformat\avformat.lib(mov.o)(.text+0x1f5a): In  
function `
mov_read_cmov':
c:/develop/ffmpeg-0.4.9-pre1/libavformat/mov.c:1412: undefined reference  
to `unc
ompress'


-- 
shelarcy <shelarcy capella.freemail.ne.jp>
http://page.freett.com/shelarcy/