xiaoyafeng has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I've download fmod music dll and intend to write a mp3 player in perl.

because I'm a little new to Inline::C, I wanna simply wrap a C function to test after refer to Inline::C-Cookbook:
use warnings; use strict; use Inline C => Config => LIBS => '-lfmodex'; use Inline C => << 'TEST'; #include "fmod.h" #include "fmod_errors.h" #include <windows.h> #include <stdio.h> #include <conio.h> int playstream(char * name) { FMOD_SYSTEM *system; FMOD_SOUND *sound1, *sound2, *sound3; FMOD_CHANNEL *channel = 0; FMOD_RESULT result; int key; unsigned int version; /* Create a System object and initialize. */ result = FMOD_System_Create(&system); ERRCHECK(result); result = FMOD_System_GetVersion(system, &version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. Th +is program requires %08x\n", version, FMOD_VERSION); return 0; } result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, NULL); ERRCHECK(result); result = FMOD_System_CreateSound(system, "../media/drumloop.wav", +FMOD_HARDWARE | FMOD_LOOP_OFF, 0, &sound1); ERRCHECK(result); result = FMOD_Sound_SetMode(sound1, FMOD_LOOP_OFF); ERRCHECK(result); result = FMOD_System_CreateSound(system, "../media/survey.mp3", FM +OD_SOFTWARE, 0, &sound2); ERRCHECK(result); result = FMOD_System_CreateSound(system, "../media/swish.wav", FMO +D_HARDWARE, 0, &sound3); ERRCHECK(result); printf("========================================================== +=========\n"); printf("PlaySound Example. Copyright (c) Firelight Technologies 2 +004-2005.\n"); printf("========================================================== +=========\n"); printf("\n"); printf("Press '1' to play a mono sound using hardware mixing\n"); printf("Press '2' to play a mono sound using software mixing\n"); printf("Press '3' to play a stereo sound using hardware mixing\n") +; printf("Press 'Esc' to quit\n"); printf("\n"); /* Main loop. */ do { if (kbhit()) { key = getch(); switch (key) { case '1' : { result = FMOD_System_PlaySound(system, FMOD_CHANNE +L_FREE, sound1, 0, &channel); ERRCHECK(result); break; } case '2' : { result = FMOD_System_PlaySound(system, FMOD_CHANNE +L_FREE, sound2, 0, &channel); ERRCHECK(result); break; } case '3' : { result = FMOD_System_PlaySound(system, FMOD_CHANNE +L_FREE, sound3, 0, &channel); ERRCHECK(result); break; } } } FMOD_System_Update(system); { unsigned int ms = 0; unsigned int lenms = 0; int playing = 0; int paused = 0; int channelsplaying = 0; if (channel) { FMOD_SOUND *currentsound = 0; result = FMOD_Channel_IsPlaying(channel, &playing); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID +_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Channel_GetPaused(channel, &paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID +_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Channel_GetPosition(channel, &ms, FMOD_T +IMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID +_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } FMOD_Channel_GetCurrentSound(channel, &currentsound); if (currentsound) { result = FMOD_Sound_GetLength(currentsound, &lenms +, FMOD_TIMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INV +ALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } } result = FMOD_Sound_GetLength(sound1, &lenms, FMOD_TIMEUNI +T_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HAN +DLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } FMOD_System_GetChannelsPlaying(system, &channelsplaying); printf("Time %02d:%02d:%02d/%02d:%02d:%02d : %s : Channels + Playing %2d\r", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms + / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " + : playing ? "Playing" : "Stopped", channelsplaying); } Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ result = FMOD_Sound_Release(sound1); ERRCHECK(result); result = FMOD_Sound_Release(sound2); ERRCHECK(result); result = FMOD_Sound_Release(sound3); ERRCHECK(result); result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); return 0; } TEST
I copied fmodex.dll, fmodex.h, fmod_errors.h and fmodex_vc.lib to the script directory. But it didn't work!:
Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 Copyright (C) Microsoft Corp 1988-1998. All rights reserved. C:\Perl\bin\perl.exe C:\Perl\lib\ExtUtils\xsubpp -typemap C:\ +Perl\lib\E xtUtils\typemap main_pl_0e98.xs > main_pl_0e98.xsc && C:\Perl\bin\per +l.exe -MEx tUtils::Command -e mv main_pl_0e98.xsc main_pl_0e98.c cl -c -IC:/test -nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 + -D_CONSOL E -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HASH_SEED -DUSE_SITECUSTOMIZE -DP +ERL_IMPLIC IT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -MD +-Zi -DNDEB UG -O1 -DVERSION=\"0.00\" -DXS_VERSION=\"0.00\" "-IC:\Perl\lib\CO +RE" main _pl_0e98.c main_pl_0e98.c main_pl_0e98.xs(25) : warning C4013: 'ERRCHECK' undefined; assuming ex +tern retur ning int Running Mkbootstrap for main_pl_0e98 () C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 644 main_pl_ +0e98.bs C:\Perl\bin\perl.exe -MExtUtils::Mksymlists -e "Mksymlists('N +AME'=>\"ma in_pl_0e98\", 'DLBASE' => 'main_pl_0e98', 'DL_FUNCS' => { }, 'FUNCLIS +T' => [], 'IMPORTS' => { }, 'DL_VARS' => []);" link -out:blib\arch\auto\main_pl_0e98\main_pl_0e98.dll -dll -n +ologo -nod efaultlib -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE" -machine:x +86 main_pl _0e98.obj C:\Perl\lib\CORE\perl58.lib "C:\Program Files\Microsoft Vi +sual Studi o\VC98\lib\oldnames.lib" "C:\Program Files\Microsoft Visual Studio\VC9 +8\lib\kern el32.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\user32.li +b" "C:\Pro gram Files\Microsoft Visual Studio\VC98\lib\gdi32.lib" "C:\Program Fil +es\Microso ft Visual Studio\VC98\lib\winspool.lib" "C:\Program Files\Microsoft Vi +sual Studi o\VC98\lib\comdlg32.lib" "C:\Program Files\Microsoft Visual Studio\VC9 +8\lib\adva pi32.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\shell32.l +ib" "C:\Pr ogram Files\Microsoft Visual Studio\VC98\lib\ole32.lib" "C:\Program Fi +les\Micros oft Visual Studio\VC98\lib\oleaut32.lib" "C:\Program Files\Microsoft V +isual Stud io\VC98\lib\netapi32.lib" "C:\Program Files\Microsoft Visual Studio\VC +98\lib\uui d.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\ws2_32.lib" +"C:\Progra m Files\Microsoft Visual Studio\VC98\lib\mpr.lib" "C:\Program Files\Mi +crosoft Vi sual Studio\VC98\lib\winmm.lib" "C:\Program Files\Microsoft Visual Stu +dio\VC98\l ib\version.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\odb +c32.lib" " C:\Program Files\Microsoft Visual Studio\VC98\lib\odbccp32.lib" "C:\Pr +ogram File s\Microsoft Visual Studio\VC98\lib\msvcrt.lib" -def:main_pl_0e98.def Creating library blib\arch\auto\main_pl_0e98\main_pl_0e98.lib and o +bject blib \arch\auto\main_pl_0e98\main_pl_0e98.exp main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Releas e@4 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Close@ 4 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sou +nd_Release @4 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_GetCha nnelsPlaying@8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sou +nd_GetLeng th@12 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Cha +nnel_GetCu rrentSound@8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Cha +nnel_GetPo sition@12 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Cha +nnel_GetPa used@8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Cha +nnel_IsPla ying@8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Update @4 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_PlaySo und@20 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sou +nd_SetMode @8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Create Sound@20 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Init@1 6 main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_GetVer sion@8 main_pl_0e98.obj : error LNK2001: unresolved external symbol _ERRCHECK main_pl_0e98.obj : error LNK2001: unresolved external symbol _FMOD_Sys +tem_Create @4 blib\arch\auto\main_pl_0e98\main_pl_0e98.dll : fatal error LNK1120: 17 + unresolve d externals NMAKE : fatal error U1077: 'link' : return code '0x460' Stop.
It looks like I need to tell Inline which library file to link. But How can I specify link's parameters? I just know to copied fmodex_vc.lib to the script directory. I couldn't find any clue to set link configuration in Inline::C-Cookbook.

Any suggestions? Thanks in advance!

I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Replies are listed 'Best First'.
Re: Inlin::C in Win32
by syphilis (Archbishop) on Nov 06, 2007 at 09:05 UTC
    use Inline C => Config => LIBS => '-lfmodex';
    That won't link to fmodex_vc.lib. You would need:
    LIBS => '-lfmodex_vc';
    But then, since fmodex_vc.lib is in a non-standard location, you also need to tell the linker where fmodex_vc.lib is located. Therefore:
    LIBS => '-LC:/full/path/to/lib -lfmodex_vc';
    Since the lib is in the cwd, the following might suffice:
    LIBS => '-L. -lfmodex_vc';
    However, I'm not sure whether a relative path works with Inline::C ... if it doesn't, then provide the full path.

    Cheers,
    Rob
Re: Inlin::C in Win32
by Corion (Patriarch) on Nov 06, 2007 at 08:42 UTC

    This is propably not what you want - as I'm not really good with C, I usually wrap the functions using Win32::API, because that only leaves the parameter wrangling. As it happens, I have a wrapper for the Fmod DLL (or is it BASS.dll?). But this doesn't help you with your Inline::C linkage problem.

    Searching for "library" in the Inline::C Cookbook, I find the following snippet under Exposing Shared Libraries, which could be the magic you're looking for:

    use Inline C => Config => LIBS => '-lghttp';

    So maybe all you need is to use:

    use Inline C => Config => LIBS => '-lfmodex_vc';

    to load fmodex_vc.lib?

      Unfortunately, it doesn't work yet after I change:
      LIBS => '-lfmodex'; to LIBS => '-lfmodex_vc';
      I doubt I have to inform Inline where library is explicitly like:
      LD => ....
      But I'm not sure.

      I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction
Re: Inlin::C in Win32
by xiaoyafeng (Deacon) on Nov 07, 2007 at 00:03 UTC
    Thank everybody replyed, It works! Give me some time, I'll post my code. ;)

    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction
      I'm also having this issue can you the details how it worked
        Please send me the details as i'm getting the same error. i'm trying to call functions from cpp dll bellow is my code se Inline C => DATA => LIBS => '-lRemote'; $text = 'Testing wrapper dll funcs...'; my_Run(); __END__ __C__ #include <Remote.h> int my_Run(){ Run(); // This function is defined in dll file }