RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 708052
Accepted
eanmos
eanmos
Asked:2020-08-20 00:58:36 +0000 UTC2020-08-20 00:58:36 +0000 UTC 2020-08-20 00:58:36 +0000 UTC

低音问题

  • 772

我正在尝试编译此代码:

/*
    BASS simple console player
    Copyright (c) 1999-2015 Un4seen Developments Ltd.
*/

#include <stdlib.h>
#include <stdio.h>
#define BASSDEF(f) (WINAPI *f) // define the functions as pointers
#include "bass.h"

#ifdef _WIN32 // Windows
#include <conio.h>
#else // OSX/Linux
#include <sys/time.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>

#define Sleep(x) usleep(x*1000)

int _kbhit()
{
    int r;
    fd_set rfds;
    struct timeval tv={0};
    struct termios term,oterm;
    tcgetattr(0,&oterm);
    memcpy(&term,&oterm,sizeof(term));
    cfmakeraw(&term);
    tcsetattr(0,TCSANOW,&term);
    FD_ZERO(&rfds);
    FD_SET(0,&rfds);
    r=select(1,&rfds,NULL,NULL,&tv);
    tcsetattr(0,TCSANOW,&oterm);
    return r;
}
#endif

// display error messages
void Error(const char *text) 
{
    printf("Error(%d): %s\n",BASS_ErrorGetCode(),text);
    BASS_Free();
    exit(0);
}

void ListDevices()
{
    BASS_DEVICEINFO di;
    int a;
    for (a=1;BASS_GetDeviceInfo(a,&di);a++) {
        if (di.flags&BASS_DEVICE_ENABLED) // enabled output device
            printf("dev %d: %s\n",a,di.name);
    }
}

void main(int argc, char **argv)
{
    DWORD chan,act,time,level;
    BOOL ismod;
    QWORD pos;
    int a,device=-1;

    printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player\n"
            "---------------------------------------------------------\n");

    // check the correct BASS was loaded
    if (HIWORD(BASS_GetVersion())!=BASSVERSION) {
        printf("An incorrect version of BASS was loaded");
        return;
    }

    for (a=1;a<argc;a++) {
        if (!strcmp(argv[a],"-l")) {
            ListDevices();
            return;
        } else if (!strcmp(argv[a],"-d") && a+1<argc) device=atoi(argv[++a]);
        else break;
    }
    if (a!=argc-1) {
        printf("\tusage: contest [-l] [-d #] <file>\n"
            "\t-l = list devices\n"
            "\t-d = device number\n");
        return;
    }

    // initialize output device
    if (!BASS_Init(device,44100,0,0,NULL))
        Error("Can't initialize device");

    // try streaming the file/url
    if ((chan=BASS_StreamCreateFile(FALSE,argv[argc-1],0,0,BASS_SAMPLE_LOOP))
        || (chan=BASS_StreamCreateURL(argv[argc-1],0,BASS_SAMPLE_LOOP,0,0))) {
        pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE);
        if (BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)!=-1) {
            // streaming from the internet
            if (pos!=-1)
#ifdef _WIN32
                printf("streaming internet file [%I64d bytes]",pos);
#else
                printf("streaming internet file [%lld bytes]",pos);
#endif
            else
                printf("streaming internet file");
        } else
#ifdef _WIN32
            printf("streaming file [%I64d bytes]",pos);
#else
            printf("streaming file [%lld bytes]",pos);
#endif
        ismod=FALSE;
    } else {
        // try loading the MOD (with looping, sensitive ramping, and calculate the duration)
        if (!(chan=BASS_MusicLoad(FALSE,argv[argc-1],0,0,BASS_SAMPLE_LOOP|BASS_MUSIC_RAMPS|BASS_MUSIC_PRESCAN,1)))
            // not a MOD either
            Error("Can't play the file");
        { // count channels
            float dummy;
            for (a=0;BASS_ChannelGetAttribute(chan,BASS_ATTRIB_MUSIC_VOL_CHAN+a,&dummy);a++);
        }
        printf("playing MOD music \"%s\" [%u chans, %u orders]",
            BASS_ChannelGetTags(chan,BASS_TAG_MUSIC_NAME),a,(DWORD)BASS_ChannelGetLength(chan,BASS_POS_MUSIC_ORDER));
        pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE);
        ismod=TRUE;
    }

    // display the time length
    if (pos!=-1) {
        time=(DWORD)BASS_ChannelBytes2Seconds(chan,pos);
        printf(" %u:%02u\n",time/60,time%60);
    } else // no time length available
        printf("\n");

    BASS_ChannelPlay(chan,FALSE);

    while (!_kbhit() && (act=BASS_ChannelIsActive(chan))) {
        // display some stuff and wait a bit
        level=BASS_ChannelGetLevel(chan);
        pos=BASS_ChannelGetPosition(chan,BASS_POS_BYTE);
        time=BASS_ChannelBytes2Seconds(chan,pos);
#ifdef _WIN32
        printf("pos %09I64u",pos);
#else
        printf("pos %09llu",pos);
#endif
        if (ismod) {
            pos=BASS_ChannelGetPosition(chan,BASS_POS_MUSIC_ORDER);
            printf(" (%03u:%03u)",LOWORD(pos),HIWORD(pos));
        }
        printf(" - %u:%02u - L ",time/60,time%60);
        if (act==BASS_ACTIVE_STALLED) { // playback has stalled
            printf("-- buffering : %05u --",(DWORD)BASS_StreamGetFilePosition(chan,BASS_FILEPOS_BUFFER));
        } else {
            for (a=27204;a>200;a=a*2/3) putchar(LOWORD(level)>=a?'*':'-');
            putchar(' ');
            for (a=210;a<32768;a=a*3/2) putchar(HIWORD(level)>=a?'*':'-');
        }
        printf(" R - cpu %.2f%%  \r",BASS_GetCPU());
        fflush(stdout);
        Sleep(50);
    }
    printf("                                                                             \r");

    // wind the frequency down...
    BASS_ChannelSlideAttribute(chan,BASS_ATTRIB_FREQ,1000,500);
    Sleep(300);
    // ...and fade-out to avoid a "click"
    BASS_ChannelSlideAttribute(chan,BASS_ATTRIB_VOL,-1,200);
    // wait for slide to finish
    while (BASS_ChannelIsSliding(chan,0)) Sleep(1);

    BASS_Free();
}

此示例开箱即用。我只是从自己添加的

#define BASSDEF(f) (WINAPI* f) // define the functions as pointers

否则它不会。启动程序后,没有打开窗口,它立即崩溃。gdb写入

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()

(gdb) bt
#0  0x00000000 in ?? ()
#1  0x004015c1 in main (argc=1, argv=0xdc15b0) at qks.c:68

即使这个例子也不起作用:

#define BASSDEF(f) (WINAPI *f)
#include "bass.h"

int main() {
    BASS_Init(-1, 44100, 0, 0, NULL);
}

我这样编译:

gcc.exe -m32 -Wall -Wextra -Wpedantic -lbass -mwindows qks.c -o qks.exe

操作系统- Windows 10 x64;海湾合作委员会-4.9.2

UPD

进展甚微。该程序编译并成功完成:

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#define BASSDEF(f) (WINAPI *f)
#include "bass.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) {
    (void) hPrevInstance, (void) lpCmdLine, (void) nCmdShow;

    HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS
    BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
    BASS_Init(-1,44100,0,NULL,NULL) // call BASS_Init
}

以下是文档中写的内容:

缺点是您必须使用该功能手动导入您使用的每个GetProcAddress功能。但是通过使用BASSDEF #define. 这是一个小例子:

#define BASSDEF(f) (WINAPI *f) // define the functions as pointers
#include "bass.h" ... HINSTANCE bass=LoadLibrary("BASS.DLL"); // load BASS
BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
BASS_Init(-1,44100,0,hWnd,NULL); // call BASS_Init

但是,当我尝试获取其他函数的地址时,我收到一个警告:

warning: assignment from incompatible pointer type
  BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");

如果您调用此函数(或任何其他函数),则SIGSEGV.

更新 2

如果将main这些行添加到正文的开头,则上面的示例有效:

HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS
BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
BASS_Free=GetProcAddress(bass,"BASS_Free");
BASS_SetVolume=GetProcAddress(bass,"BASS_SetVolume");
BASS_SetConfig=GetProcAddress(bass,"BASS_SetConfig");
BASS_SampleFree=GetProcAddress(bass,"BASS_SampleFree");
BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad");
BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel");
BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay");
BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop");
BASS_GetVolume=GetProcAddress(bass,"BASS_GetVolume");
BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
BASS_GetCPU=GetProcAddress(bass,"BASS_GetCPU");
BASS_Pause=GetProcAddress(bass,"BASS_Pause");
BASS_Start=GetProcAddress(bass,"BASS_Start");
BASS_MusicFree=GetProcAddress(bass,"BASS_MusicFree");
BASS_MusicLoad=GetProcAddress(bass,"BASS_MusicLoad");
BASS_ChannelSetAttribute=GetProcAddress(bass,"BASS_ChannelSetAttribute");
BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile");
BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode");
BASS_StreamCreateURL=GetProcAddress(bass, "BASS_StreamCreateURL");
BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength");
BASS_StreamGetFilePosition=GetProcAddress(bass, "BASS_StreamGetFilePosition");
BASS_ChannelGetAttribute=GetProcAddress(bass, "BASS_ChannelGetAttribute");
BASS_ChannelGetTags=GetProcAddress(bass, "BASS_ChannelGetTags");
BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength");
BASS_ChannelBytes2Seconds=GetProcAddress(bass, "BASS_ChannelBytes2Seconds");
BASS_ChannelIsActive=GetProcAddress(bass, "BASS_ChannelIsActive");
BASS_ChannelGetLevel=GetProcAddress(bass, "BASS_ChannelGetLevel");
BASS_ChannelGetPosition=GetProcAddress(bass, "BASS_ChannelGetPosition");
BASS_ChannelSlideAttribute=GetProcAddress(bass, "BASS_ChannelSlideAttribute");

一大“ BUT ”:从命令行运行时播放声音(cmd.exe,ConEmu),但没有文字信息。那些。我运行程序,它在后台运行,输入提示立即出现在终端:

user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound 
> qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3"   

user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound 
>             

但是,所有文本信息(声音也可以)出现在内置控制台中SublimeText 3:

C:\Users\user\Documents\Projects\sound>qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3" 
Simple console mode BASS example : MOD/MPx/OGG/WAV player
---------------------------------------------------------
streaming file [41587200 bytes] 3:55
pos 000000136 - 0:00 - L ------------- ------------- R - cpu 0.00%  
pos 000005944 - 0:00 - L ------------- ------------- R - cpu 0.00%  
pos 000014808 - 0:00 - L ------------- ------------- R - cpu 0.00%  
pos 000023728 - 0:00 - L ------------- ------------- R - cpu 0.00%  
pos 000032628 - 0:00 - L ------------- ------------- R - cpu 0.07%  
pos 000041584 - 0:00 - L ---********** **********--- R - cpu 0.07%  
pos 000050496 - 0:00 - L -----******** ********----- R - cpu 0.14%  
pos 000059536 - 0:00 - L -----******** *********---- R - cpu 0.14%  
pos 000068572 - 0:00 - L -----******** *********---- R - cpu 0.19%  
pos 000077544 - 0:00 - L -----******** ********----- R - cpu 0.19%  
pos 000086464 - 0:00 - L -----******** *********---- R - cpu 0.25%  
pos 000095364 - 0:00 - L -----******** ********----- R - cpu 0.25%
...

编译器信息(gcc -v):

Using built-in specs.
COLLECT_GCC=gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.1/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.8.1/configure --build=x86_64-w64-mingw32 --enable-targets=all --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-libgomp --enable-lto --enable-graphite --enable-cxx-flags=-DWINPTHREAD_STATIC --enable-libstdcxx-debug --enable-threads=posix --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libstdcxx-threads --enable-libstdcxx-time --with-gnu-ld --disable-werror --disable-nls --disable-win32-registry --prefix=/mingw64tdm --with-local-prefix=/mingw64tdm --with-pkgversion=tdm64-2 --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: posix
gcc version 4.8.1 (tdm64-2)

调试:

user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound
> gdb.exe qks.exe
GNU gdb (GDB) 7.7.50.20140303-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".

This binary was built by Equation Solution <http://www.Equation.com>...
Reading symbols from qks.exe...done.
(gdb) b main
Breakpoint 1 at 0x4015c5: file qks.c, line 59.
(gdb) r -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3"
Starting program: C:\Users\user\Documents\Projects\sound\qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3"
[New Thread 2708.0x16f4]
[New Thread 2708.0x4c0]

Breakpoint 1, main (argc=4, argv=0xab2390) at qks.c:59
59              HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS
(gdb) n
[New Thread 2708.0xd28]
60              BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
(gdb)
61              BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
(gdb)
62              BASS_Free=GetProcAddress(bass,"BASS_Free");
(gdb)
63              BASS_SetVolume=GetProcAddress(bass,"BASS_SetVolume");
(gdb)
64              BASS_SetConfig=GetProcAddress(bass,"BASS_SetConfig");
(gdb)
65              BASS_SampleFree=GetProcAddress(bass,"BASS_SampleFree");
(gdb)
66              BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad");
(gdb)
67              BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel");
(gdb)
68              BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay");
(gdb)
69              BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop");
(gdb)
70              BASS_GetVolume=GetProcAddress(bass,"BASS_GetVolume");
(gdb)
71              BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
(gdb)
72              BASS_GetCPU=GetProcAddress(bass,"BASS_GetCPU");
(gdb)
73              BASS_Pause=GetProcAddress(bass,"BASS_Pause");
(gdb)
74              BASS_Start=GetProcAddress(bass,"BASS_Start");
(gdb)
75              BASS_MusicFree=GetProcAddress(bass,"BASS_MusicFree");
(gdb)
76              BASS_MusicLoad=GetProcAddress(bass,"BASS_MusicLoad");
(gdb)
77              BASS_ChannelSetAttribute=GetProcAddress(bass,"BASS_ChannelSetAttribute");
(gdb)
78              BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile");
(gdb)
79              BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode");
(gdb)
80              BASS_StreamCreateURL=GetProcAddress(bass, "BASS_StreamCreateURL");
(gdb)
81              BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength");
(gdb)
82              BASS_StreamGetFilePosition=GetProcAddress(bass, "BASS_StreamGetFilePosition");
(gdb)
83              BASS_ChannelGetAttribute=GetProcAddress(bass, "BASS_ChannelGetAttribute");
(gdb)
84              BASS_ChannelGetTags=GetProcAddress(bass, "BASS_ChannelGetTags");
(gdb)
85              BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength");
(gdb)
86              BASS_ChannelBytes2Seconds=GetProcAddress(bass, "BASS_ChannelBytes2Seconds");
(gdb)
87              BASS_ChannelIsActive=GetProcAddress(bass, "BASS_ChannelIsActive");
(gdb)
88              BASS_ChannelGetLevel=GetProcAddress(bass, "BASS_ChannelGetLevel");
(gdb)
89              BASS_ChannelGetPosition=GetProcAddress(bass, "BASS_ChannelGetPosition");
(gdb)
90              BASS_ChannelSlideAttribute=GetProcAddress(bass, "BASS_ChannelSlideAttribute");
(gdb)
95          int a,device=-1;
(gdb)
97          printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player\n"
(gdb)
101         if (HIWORD(BASS_GetVersion())!=BASSVERSION) {
(gdb)
0x744d59c6 in ?? ()
(gdb) ni
0x744b10f9 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45c5 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45c6 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45cc in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45d2 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45d4 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45d6 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45ee in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45f0 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b45f1 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b10fe in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b1101 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b1103 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b1104 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744d59cb in ?? ()
(gdb)
0x744d59d0 in ?? ()
(gdb)
0x00401976 in main (argc=4, argv=0xab2390) at qks.c:101
101         if (HIWORD(BASS_GetVersion())!=BASSVERSION) {
(gdb) n
106         for (a=1;a<argc;a++) {
(gdb)
107             if (!strcmp(argv[a],"-l")) {
(gdb)
110             } else if (!strcmp(argv[a],"-d") && a+1<argc) device=atoi(argv[++a]);
(gdb)
106         for (a=1;a<argc;a++) {
(gdb)
107             if (!strcmp(argv[a],"-l")) {
(gdb)
110             } else if (!strcmp(argv[a],"-d") && a+1<argc) device=atoi(argv[++a]);
(gdb)
113         if (a!=argc-1) {
(gdb)
121         if (!BASS_Init(device,44100,0,0,NULL))
(gdb)
0x744d3dc5 in ?? ()
(gdb) ni
0x744d3dc6 in ?? ()
(gdb)
0x744d3dca in ?? ()
(gdb)
0x744d3dcd in ?? ()
(gdb)
0x744d3dd3 in ?? ()
(gdb)
0x744d3dd4 in ?? ()
(gdb)
0x744d3dd5 in ?? ()
(gdb)
0x744b462e in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b4630 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b4644 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b4646 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744d3dda in ?? ()
(gdb)
0x744d3ddc in ?? ()
(gdb)
0x744d3dde in ?? ()
(gdb)
0x744d3de0 in ?? ()
(gdb)
0x744d3de2 in ?? ()
(gdb)
0x744d3de3 in ?? ()
(gdb)
0x744d3da9 in ?? ()
(gdb)
0x744d3daa in ?? ()
(gdb)
0x744b470b in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
0x744b4710 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll
(gdb)
[New Thread 2708.0x109c]
[New Thread 2708.0x1098]
[New Thread 2708.0xcdc]
[New Thread 2708.0x760]
[New Thread 2708.0x1674]
[New Thread 2708.0x1834]
[New Thread 2708.0x390]
[New Thread 2708.0x1314] <-- здесь начинает играть музыка
                             программу пришлось "убивать" через диспетчер
                             задач, т.к. музыка играет заново снова и снова.   
[Thread 2708.0xd28 exited with code 1]
[Thread 2708.0x4c0 exited with code 1]
[Thread 2708.0x109c exited with code 1]
[Thread 2708.0xcdc exited with code 1]
[Thread 2708.0x1098 exited with code 1]
[Thread 2708.0x1674 exited with code 1]
[Thread 2708.0x760 exited with code 1]
[Thread 2708.0x1834 exited with code 1]
[Thread 2708.0x390 exited with code 1]
[Thread 2708.0x1314 exited with code 1]
[Inferior 1 (process 2708) exited with code 01]

系统:

OS: Windows 10 x64
CPU: AMD A9-9410 RADEON R5, COMPUTE CORES 2C+3G  2.90 GHz

编译和运行命令:

gcc.exe -g -std=c11 -m32 -Wall -Wextra -Wpedantic -lbass -mwindows qks.c -o qks.exe
qks.exe -d -1 "C:\Users\user\Music\Eminem\Rap God.mp3"
c
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    KoVadim
    2020-08-23T20:35:07Z2020-08-23T20:35:07Z

    Есть такая штука - ABI - то есть описание того, как функция/класс будет представлена в бинарном виде. Это очень важно, когда линкуются два разных куска кода (например, exe и статическая библиотка) или просто вызываются (например, обращение к dll). В некоторых случаях линковщик (а это его работа) может проверить, что интерфейс не совпадает и поднять панику. А может и не знать или проигнорировать.

    Если два куска кода не совместимы на уровне ABI, то может произойти все что угодно. Самый простой пример - вызывающая сторона ожидает параметры в регистрах, а вызываемая - в стеке. Что именно прочитается со стека - никто не знает. В лучшем случае упадет с Access violation.

    В случае чистого Си эту проблему достаточно хорошо решили (всякие stdcall, cdecl и подобное). А вот в случае с++ все сильно сложнее - есть классы, а им нужно хранить данные, которые никак не стандартизированы. Даже если использовать только gcc, он может использовать различное ABI. Из последнего, на что я лично натолкнулся, это сильно измененный ABI при переходе от 4.9.х на 5.4.х (он вроде после 5.2 поменялся). Здесь есть много деталей.

    Теперь ближе к проблеме. По внешнему виду файла обычно сложно догадаться, какой версией компилятора он собран. Но её можно попробовать угадать. Судя по всему, там внутри все собрано с помощью vc6 (это очень древнее существо) и более-менее свежие gcc с ним поэтому и не совместимы. А старые - да. @VadimTagil просто повезло, что он угадал правильную версию.

    Что делать? использовать gcc 3.4 как не очень, как по мне, поэтому, лучше взять сорцы и пересобрать их именно тем gcc, которым будет собираться все остальное. Благое дело, там есть makefile и студийный проект.

    • 4
  2. MSDN.WhiteKnight
    2020-08-23T15:33:46Z2020-08-23T15:33:46Z

    Ну, предупреждение "assignment from incompatible pointer type" вполне логично. GetProcAddress возвращает указатель на функцию с неопределенным списком параметров, возвращающую int. Приведение к любым другим указателям выведет это предупреждение. Его можно игнорировать.

    Что касается Segmentation Fault, у меня ничего такого не наблюдается. BASS_GetVersion, BASS_GetDeviceInfo нормально работают. Либо вы не ту версию DLL-ки подкладываете (32-битную вместо 64-битной или наоборот), либо какая-то локальная проблема с вашей системой.

    UPD: На всякий случай, мой рабочий пример:

    #include <stdlib.h>
    #include <stdio.h>
    #define BASSDEF(f) (WINAPI *f) // define the functions as pointers
    #include "bass.h"
    #include <conio.h>
    
    void ListDevices()
    {
        BASS_DEVICEINFO di;
        int a;
        for (a=1;BASS_GetDeviceInfo(a,&di);a++) {
            if (di.flags&BASS_DEVICE_ENABLED) // enabled output device
                printf("dev %d: %s\n",a,di.name);
        }
    }
    
    void main(int argc, char **argv)
    {
        HINSTANCE bass=LoadLibrary("BASS.DLL"); // load BASS
        BASS_Init=GetProcAddress(bass,"BASS_Init");
        BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
        BASS_GetDeviceInfo=GetProcAddress(bass,"BASS_GetDeviceInfo");
    
        // check the correct BASS was loaded
        DWORD ver;
        ver=BASS_GetVersion();
        if (HIWORD(ver)!=BASSVERSION) {
            printf("An incorrect version of BASS was loaded");
            return;
        }
        else
        {
            printf("BASS version is %d\n\n",ver);
        }
    
        ListDevices();
        system("pause");
    }
    

    Компилируется и успешно работает (выводит список устройств), тестировалось на:

    • Windows 7 x64
    • GCC 3.4.2, 4.9.2 (32-битный режим)
    • BASS 2.4
    • 3
  3. Eugene Krivenja
    2020-08-22T03:37:36Z2020-08-22T03:37:36Z

    也许我自己添加的应该是这样的:

    #ifndef BASSDEF
    #ifdef WIN32
    #define BASSDEF(f) WINAPI f
    #else
    #define BASSDEF(f) f
    #endif
    #endif
    

    取自这里 https://github.com/kusma/spaceflowers/blob/master/bassmod/bassmod.h

    或者就像这样:

    #define BASSDEF(f) WINAPI f
    

    https://github.com/sonicretro/sadx-mod-loader/blob/master/extlib/bass/bass.h

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5