2

I'm trying to code a little program with a simple number guessing game.

I want to play an mp3 file behind it using a simple thread. I have read How to play or open *.mp3 or *.wav sound file in c++ program?, but I can't get it to work. It always spews out the error:

||=== Build: Debug in pinkpantherguessinggame (compiler: GNU GCC Compiler) ===|
C:\Users\Leon\Desktop\pCode\pinkpantherguessinggame\main.cpp|8|warning: ignoring #pragma comment  [-Wunknown-pragmas]|
obj\Debug\main.o||In function `Z11pinkpantherv':|
C:\Users\Leon\Desktop\pCode\pinkpantherguessinggame\main.cpp|16|undefined reference to `_imp__mciSendStringA@16'|
||error: ld returned 1 exit status|
||=== Build failed: 2 error(s), 1 warning(s) (0 minute(s), 1 second(s)) ===|

Here is my code:

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <windows.h>
#include <thread>
#include <Mmsystem.h>

#pragma comment(lib, "Winmm.lib")

using namespace std;

void start(int);

void pinkpanther()
{
    mciSendString("open \"‪E:\\Users\\cdev\\Musik\\pinkpanther.mp\" type mpegvideo alias mp3", NULL, 0, NULL);
    mciSendString("play mp3", NULL, 0, NULL);
}

I tried downloading winmm.lib from somewhere, because it doesn't seem to find the library (just a guess).

Am I doing something wrong, or do I need to include some other header?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Grimmboy
  • 33
  • 2
  • 6
  • Something seems amiss when you are using gcc but want to link a windows library with pragma... I beleive pragma is visual studio only, but I am not 100% sure as I don't use anything else. You might want to look into how to link libraries with your particular compiler and whether those windows libraries are available at all in that environment. – Christopher Pisz Aug 24 '18 at 16:51
  • *Read* the error message. "main.cpp|16|undefined reference to `_imp__mciSendStringA" tells you *exactly* what the problem is (you may want to demangle the function name for greater readability though). You are calling a function that is not provided by whatever object files/library files you are linking with (and you even got told *what* function). Most likely you just need to tell the linker about the one missing file that is defining the missing symbol. – Jesper Juhl Aug 24 '18 at 16:53
  • @jesper its undefined most likely, because he isnt even linking. I see a message about ignoring the pragma he is trying to use to link with. – Christopher Pisz Aug 24 '18 at 16:55
  • 2
    "I tried downloading winmm.lib from somewhere" - ehh. That seems like a *really* bad idea. *Don't* just download and run random binaries from random sites on the internet. Instead; find out what the problem *actually* is, then if you are missing a library, find the official (hopefully trustworthy) distribution point, then download from there (preferably as source ypu can inspect before compiling rather than just trusting a binary). – Jesper Juhl Aug 24 '18 at 16:58
  • @Christopher Pisz - I think you are right. The source has "`#pragma comment(lib, "Winmm.lib")`". Talk about tying yourself to a specific platform. That's *not* the right cross-platform way to link libraries. – Jesper Juhl Aug 24 '18 at 17:02
  • @JesperJuhl: Yeah, right. Use CMake! Now you have two problems. In all seriousness, the issue here is about blindly copying code you do not understand. That issue is not solved by writing portable code. – IInspectable Aug 24 '18 at 17:16

3 Answers3

2

If you read the compiler output carefully, you will see this warning:

warning: ignoring #pragma comment [-Wunknown-pragmas]

That means your compiler (GCC) does not support your code's use of #pragma comment, and so winmm.lib ends up not getting linked into your final executable, thus causing the subsequent linker error:

undefined reference to `_imp__mciSendStringA@16'

This is not a matter of the linker not being able to find winmm.lib, it is a matter of the linker not being told to use winmm.lib in the first place.

#pragma is used to invoke compiler-specific commands. Not all compilers implement #pragma comment. VC++ does (and so do a few others, like BCC32/64), but GCC does not. The other question you linked to was tagged visual-c++, so #pragma comment was appropriate in that case.

In your case, you will have to adjust your build process accordingly to use another way to tell the linker to use winmm.lib. You do that in GCC by using the -l option when invoking the linker, eg -lwinmm.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    this helped immensely! i looked up how to link libraries in my IDE, then it worked like a charm, the code does not play my mp3 but thats another problem on its own! Thank you! – Grimmboy Aug 24 '18 at 17:23
  • Small note : *gcc* (if part of *MinGW*, but I think it also applies to other build toolchains) will link to *libwinmm.a* (which is also part of the toolchain). In some cases the formats don't even match like I showed (for *clang*) in https://stackoverflow.com/questions/45340527/how-to-circumvent-windows-universal-crt-headers-dependency-on-vcruntime-h/50838055#50838055 (somewhere at the middle). – CristiFati Aug 24 '18 at 18:25
1

For future visitors that use gcc or g++, we can link the library manually by specifying -l flag, so the ld.exe (linker) can find it.

g++ test.cpp -o test.exe -lWinmm

A5H1Q
  • 544
  • 7
  • 15
0

I just tried to use gcc multimedia.c -o multimedia -l Winmm with pragma but it did not work I got

multimedia.c: In function 'int main()':
multimedia.c:5:5: error: 'mciSendString' was not declared in this scope
    5 |     mciSendString("open video.mpg alias file1");
Fildo7525
  • 13
  • 4