0

Microsoft VisualStudio2010にC++コードをコンソールプログラムとして提供するという概念実証を完了したばかりです。コンパイルされたC++コードを以下に示します。

#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <sndfile.h>


//The following libraries are related to parsing the text files
#include <iostream> //Open the file 
#include <fstream> //Reading to and from files



//The following libraries are for conducting the DTW analysis
#include "dtw.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    printf("This is a test\n");


    //This will be the length of the buffer used to hold samples while the program processes them. 


    //A SNDFILE is like FILE in a standard C library. Consequently, the sf_open_read and sf_open_write functions will return an 
    //SNDFILE* pointer when they successfully open the specified file. 
    SNDFILE* sf = NULL; 

    /*SF_INFO will obtain information of the file we wish to load into our program. */
    SF_INFO info; 

    /*The following is descriptive information to obtain from wave files. These are declarations*/
    int num_channels;
    double num, num_items;S
    double *buf; 
    int f, sr, c; 
    int i,j;
    FILE *out; 


    /*This is where the program will open the WAV file */
    info.format = 0; 
    sf = sf_open("C:\\Users\\GeekyOmega\\Desktop\\gameon.wav", SFM_READ, &info);
    if(sf == NULL)
    {
        printf("Failed to open the file.\n");
        getchar();
        exit(-1);
    }

    /*Print some file information */
    f = info.frames;
    sr = info.samplerate;
    c = info.channels;

    /*Print information related to file*/
    printf("frames = %d\n",f);
    printf("sample rate = %d\n",sr);
    printf("channels = %d\n",c);

    /*Calculate and print the number of items*/  
    num_items = f*c;
    printf("Read %lf items\n", num_items);

    /*Allocate space for the data to be read*/
    buf = (double *) malloc(num_items*sizeof(double));
    num = sf_read_double(sf,buf,num_items);
    sf_close(sf);

    /*print the information*/
    printf("Read %lf items\n", num);



    /*Write the data to the filedata.out*/  
    out = fopen("filedata.txt", "w");
    for(i = 0; i < num; i+=c)
    {
        for(j = 0; j < c; ++j)
        {
            fprintf(out, "%lf ", buf[i +j]);
        }
        fprintf(out,"\n");
    }
    fclose(out);

}

次に、これは重要ですが、これをGUIで機能させたいと思います。つまり、必要なファイルをロードすると、そのwavファイルがテキストに変換されます。私はそのコードを以下に提供します:

#pragma once
//Libraries required for libsndfile
#include <sndfile.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>


namespace WaveGui {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    using namespace System::Runtime::InteropServices;



    using namespace std;

    /// <summary>
    /// Summary for Form1
    /// </summary>

読みやすくするためにこれを編集しました。これは標準のMSVS2010フォームでした。ボタンを追加してファイルダイアログを開くだけです。

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             {

                if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                 {  
                    //Note: Ask Gustafson how we might free the memory for this strign
                    //  http://support.microsoft.com/?id=311259

                    char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(openFileDialog1->FileName);
                    SNDFILE* sf = NULL; 
                    SF_INFO info;

                    /*The following is descriptive information to obtain from wave files. These are declarations*/
                    int num_channels;
                    double num, num_items;
                    double *buf; 
                    int f, sr, c; 
                    int i,j;
                    FILE *out; 


                    /*This is where the program will open the WAV file */
                    info.format = 0; 
                    sf = sf_open(str2, SFM_READ, &info);
                    if(sf == NULL)
                    {
                        exit(-1);
                    }

                    /*Print some file information */
                    f = info.frames;
                    sr = info.samplerate;
                    c = info.channels;

                    /*Calculate and print the number of items*/  
                    num_items = f*c;

                    /*Allocate space for the data to be read*/
                    buf = (double *) malloc(num_items*sizeof(double));
                    num = sf_read_double(sf,buf,num_items);
                    sf_close(sf);

                    /*Write the data to the filedata.out*/  
                    out = fopen("filedata.txt", "w");
                    for(i = 0; i < num; i+=c)
                    {
                        for(j = 0; j < c; ++j)
                        {
                            fprintf(out, "%lf ", buf[i +j]);
                        }
                        fprintf(out,"\n");
                    }
                    fclose(out);



                 }




             }
    };
}

ボタンのコードでは、システム文字列から通常の文字列に変換してから、上記のC++コードを使用してWaveファイルをtxt情報に変換しようとしています。変換コードが機能することはわかっています。また、ボタンコードは個別にテストしたので、機能することもわかっています。ただし、ライブラリsndfile.hを使用しようとすると、実際に機能しなくなります。

ライブラリstdio.h、Windows.H、stdlib.h、iostream、fstreamを追加したときに発生するエラーは次のとおりです。

1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close@@$$J0YMHPAUSNDFILE_tag@@@Z); calling convention missing in metadata
1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double@@$$J0YM_JPAUSNDFILE_tag@@PAN_J@Z); calling convention missing in metadata
1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open@@$$J0YMPAUSNDFILE_tag@@PBDHPAUSF_INFO@@@Z); calling convention missing in metadata
1>WaveGui.obj : warning LNK4248: unresolved typeref token (01000027) for 'SNDFILE_tag'; image may not run
1>WaveGui.obj : error LNK2028: unresolved token (0A000022) "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close@@$$J0YMHPAUSNDFILE_tag@@@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>WaveGui.obj : error LNK2028: unresolved token (0A000023) "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double@@$$J0YM_JPAUSNDFILE_tag@@PAN_J@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>WaveGui.obj : error LNK2028: unresolved token (0A000025) "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open@@$$J0YMPAUSNDFILE_tag@@PBDHPAUSF_INFO@@@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close@@$$J0YMHPAUSNDFILE_tag@@@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double@@$$J0YM_JPAUSNDFILE_tag@@PAN_J@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open@@$$J0YMPAUSNDFILE_tag@@PBDHPAUSF_INFO@@@Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@Form1@WaveGui@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>c:\users\geekyomega\documents\visual studio 2010\Projects\WaveGui\Debug\WaveGui.exe : fatal error LNK1120: 6 unresolved externals

私が知る限り、私はライブラリを正しくインストールしました。結局のところ、コンソールの状況では、これらのライブラリで完全に正常に機能します。ただし、GUIフォームでまったく同じコードとライブラリを使用しようとすると、ライブラリが相互にうまく機能していないようで、その結果、.hファイルを正しく読み取れず、SNDFILEなどの構造体にアクセスできません。 。

誰かが私に何が悪いのか教えてもらえますか?私はこれに何時間も費やしてきましたが、libsndfileライブラリを廃棄する必要がないことを願っています。私は本当にそれをMSVS2010、GUIで動作させたいと思っています、そして私が知る限り、これが動作しないはずの理由はありません。しかし、あなたは彼らが言うことを知っています、コンピュータは嘘をつきません。

いつものように、あなたの患者の助けに感謝します。GeekyOmega

4

1 に答える 1

4

したがって、コンソール アプリはネイティブ コードですが、GUI アプリはマネージ C++ です。それは意図的なものでしたか、それとも GUI アプリもネイティブ (Win32) コードにするつもりでしたか?

100% ネイティブ コードを使用するか、DLL を作成してネイティブ コードをカプセル化し、.NET GUI から P/Invoke を介してそれを呼び出すと、運が良くなると思います。P/Invoke の使用例を次に示します。

http://manski.net/2012/05/29/pinvoke-tutorial-basics-part-1/

于 2012-11-02T06:17:51.583 に答える