我刚刚完成了一个概念验证,或者我认为,将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
答案 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/