none
GCC编译出来的DLL,在VC6.0中调用为什么会有不同的结果,请高手详解 RRS feed

  • 问题

  • 问题很简单,可就是不明白!
    具体情况描述如下:
    1.GCC的ffmpeg工程原本是生成.exe的,我把它修改后,现在能够生成.dll文件
    2.把生成后的dll文件搁到VC6.0中,如果我用console项目显式调用,没有任何问题;如果我用MFC的exe项目中也采用相同的调用方式就会出错,“0xC0000005:Access Violation”。
    个人认为是MFC的问题,希望高手明示!

    MFC调用DLL的代码如下:
    FFmpegConvertCodeParam ccpMy;
    ccpMy.input_file_fullpath="d:\\1.avi";
    ccpMy.fmt="flv";
    ccpMy.bitrate="512000";
    ccpMy.rfps="14.985";
    ccpMy.size="320*240";
    ccpMy.aspect="4:3";
    ccpMy.vcodec="flv";
    ccpMy.ab="128";
    ccpMy.ar="22050";
    ccpMy.ac="2";
    ccpMy.acodec="libmp3lame";
    ccpMy.output_file_fullpath="d:\\e.flv";
    ccpMy.coverted = 1;

    typedef int (*FileConvertCode)(FFmpegConvertCodeParam *);
    FileConvertCode fileConvert;
    HINSTANCE hinst;
    hinst=LoadLibrary("ffmpeg.dll");
    if(hinst==NULL)
    {
      return ;
    }
    fileConvert=(FileConvertCode)GetProcAddress(hinst,"StartCodeConvert");
    if(fileConvert==NULL)
    {
      return ;
    }
    int res = fileConvert(&ccpMy);
    FreeLibrary(hinst);

    Console项目的dll调用方式相同,而且程序运行没有错误,完全正常。

    另外补充一点的是:
    GCC编译DLL的命令如下:
    gcc -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavcodec -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/lib
    avdevice -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavfilter -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"
    /libavformat -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavutil -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpe
    g"/libpostproc -L"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libswscale -L/c/ffmpeg/libavcodec/x264/ -L/c/ffmpeg/libavcodec/faad/libfa
    ad/.libs/ -Wl,--warn-common -Wl,--as-needed -Wl,-rpath-link,"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libpostproc -Wl,-rpath-link,"/
    d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libswscale -Wl,-rpath-link,"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"
    /libavfilter -Wl,-rpath-link,"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavdevice -Wl,-rpath-link,"/d/Work/MyProject/C++/MyWork/ffm
    peg+mencoder_CodeConvert/ffmpeg"/libavformat -Wl,-rpath-link,"/d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavcodec -Wl,-rpath-link,"/
    d/Work/MyProject/C++/MyWork/ffmpeg+mencoder_CodeConvert/ffmpeg"/libavutil -Wl,-Bsymbolic -shared -s -o ffmpeg.dll ffmpeg.o cmdutils.o -lavdevice -lavformat -la
    vcodec -lavutil -lswscale -lm -lamrnb -lm -lamrwb -lm -lfaac -lfaad -lmp3lame -lm -lx264 -lm -lxvidcore -lws2_32 -lvfw32 -static
    2009年5月11日 3:38

答案

  • 用MinGW+MSYS生成编译FFMpeg后使用MFC应用程序是没问题的我试过。

    原因找到了,MFC调用dll出错的地方是一个包含有汇编代码的函数,只要把这个函数中关于汇编的代码注掉就可以解决问题。由于不明白汇编,所以暂时还尚不清楚其中缘由,还需高手继续解答。

        __asm__ volatile(
            "pxor %%xmm7,      %%xmm7         \n\t"
            "movq (%0),        %%xmm0         \n\t"
            "movq (%0, %2),    %%xmm1         \n\t"
            "movq (%0, %2,2),  %%xmm2         \n\t"
            "movq (%0, %3),    %%xmm3         \n\t"
            "lea (%0,%2,4), %0                \n\t"
            "punpcklbw %%xmm7, %%xmm0         \n\t"
            "punpcklbw %%xmm7, %%xmm1         \n\t"
            "punpcklbw %%xmm7, %%xmm2         \n\t"
            "punpcklbw %%xmm7, %%xmm3         \n\t"
            "movdqa %%xmm0,      (%1)         \n\t"
            "movdqa %%xmm1,    16(%1)         \n\t"
            "movdqa %%xmm2,    32(%1)         \n\t"
            "movdqa %%xmm3,    48(%1)         \n\t"
            "movq (%0),        %%xmm0         \n\t"
            "movq (%0, %2),    %%xmm1         \n\t"
            "movq (%0, %2,2),  %%xmm2         \n\t"
            "movq (%0, %3),    %%xmm3         \n\t"
            "punpcklbw %%xmm7, %%xmm0         \n\t"
            "punpcklbw %%xmm7, %%xmm1         \n\t"
            "punpcklbw %%xmm7, %%xmm2         \n\t"
            "punpcklbw %%xmm7, %%xmm3         \n\t"
            "movdqa %%xmm0,    64(%1)         \n\t"
            "movdqa %%xmm1,    80(%1)         \n\t"
            "movdqa %%xmm2,    96(%1)         \n\t"
            "movdqa %%xmm3,   112(%1)         \n\t"
            : "+r" (pixels)
            : "r" (block), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*3)
        );
    这个函数就是导致VC++6.0 console 项目和mfc项目在调用dll时会出错的原因
    2009年5月13日 10:40

全部回复

  • 没有用extern C 声明函数类型
    DLL导出的函数应该是C函数类型,在导入时也应该声明为C函数类型。

    MSMVP VC++
    2009年5月11日 18:10
    版主
  • 没有用extern C 声明函数类型
    DLL导出的函数应该是C函数类型,在导入时也应该声明为C函数类型。

    MSMVP VC++

    这个不是主要问题,我现在编好的DLL 在执行 “LoadLibrary” 和 "GetProcAddress" 也没有问题,只是在进入到DLL内运行后,出错。我现在琢磨会不会是,两种编译器有区别或者gcc 和 vc 在变量类型的解析上有区别
    2009年5月12日 3:55
  • 用MinGW+MSYS生成编译FFMpeg后使用MFC应用程序是没问题的我试过。
    2009年5月12日 12:18
    版主
  • 用MinGW+MSYS生成编译FFMpeg后使用MFC应用程序是没问题的我试过。

    原因找到了,MFC调用dll出错的地方是一个包含有汇编代码的函数,只要把这个函数中关于汇编的代码注掉就可以解决问题。由于不明白汇编,所以暂时还尚不清楚其中缘由,还需高手继续解答。

        __asm__ volatile(
            "pxor %%xmm7,      %%xmm7         \n\t"
            "movq (%0),        %%xmm0         \n\t"
            "movq (%0, %2),    %%xmm1         \n\t"
            "movq (%0, %2,2),  %%xmm2         \n\t"
            "movq (%0, %3),    %%xmm3         \n\t"
            "lea (%0,%2,4), %0                \n\t"
            "punpcklbw %%xmm7, %%xmm0         \n\t"
            "punpcklbw %%xmm7, %%xmm1         \n\t"
            "punpcklbw %%xmm7, %%xmm2         \n\t"
            "punpcklbw %%xmm7, %%xmm3         \n\t"
            "movdqa %%xmm0,      (%1)         \n\t"
            "movdqa %%xmm1,    16(%1)         \n\t"
            "movdqa %%xmm2,    32(%1)         \n\t"
            "movdqa %%xmm3,    48(%1)         \n\t"
            "movq (%0),        %%xmm0         \n\t"
            "movq (%0, %2),    %%xmm1         \n\t"
            "movq (%0, %2,2),  %%xmm2         \n\t"
            "movq (%0, %3),    %%xmm3         \n\t"
            "punpcklbw %%xmm7, %%xmm0         \n\t"
            "punpcklbw %%xmm7, %%xmm1         \n\t"
            "punpcklbw %%xmm7, %%xmm2         \n\t"
            "punpcklbw %%xmm7, %%xmm3         \n\t"
            "movdqa %%xmm0,    64(%1)         \n\t"
            "movdqa %%xmm1,    80(%1)         \n\t"
            "movdqa %%xmm2,    96(%1)         \n\t"
            "movdqa %%xmm3,   112(%1)         \n\t"
            : "+r" (pixels)
            : "r" (block), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*3)
        );
    这个函数就是导致VC++6.0 console 项目和mfc项目在调用dll时会出错的原因
    2009年5月13日 10:40
  • 楼主能不能把你的在console下的代码给我参考一下!!!谢谢额

    2009年7月7日 10:16