MSVS2010 C ++控制台代码移植到MSVS2010 C ++ GUI失败。为什么?

时间:2012-11-02 05:11:42

标签: c++ visual-studio user-interface libraries libsndfile

我刚刚完成了一个概念验证,或者我认为,将Microsoft Visual Studio 2010作为控制台程序提供了一些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

1 个答案:

答案 0 :(得分:4)

因此,您的控制台应用程序是本机代码,但您的GUI应用程序是托管C ++。这是故意的,还是你打算让你的GUI应用程序成为本机(Win32)代码呢?

如果您使用100%本机代码,或者创建一个DLL来封装您的本机代码并通过.NET GUI中的P / Invoke调用它,我认为您会有更好的运气。以下是使用P / Invoke的示例:

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