以下是我的代码:
//TaskConfigFile.h #pragma once using namespace System::Collections::Generic; using namespace System; using namespace System::IO; using namespace System::Text; ref class TaskConfigFile { public: TaskConfigFile(); TaskConfigFile(String^ str_link, Int64 file_size, short threads_sum); TaskConfigFile(String^ str_link, Int64 file_size); String^ link;//下载链接 String^ fileName;//文件名 String^ filePath;//文件存储路径 Int64 fileSize;//文件总大小 Int64 blockSize;//文件分块大小 Int64 sumDownloadedSize;//已下载的总大小 short threadsSum;//线程总数,默认为5 //以字典记录各分块已下载的大小,key为分块的起始位置(字节),value为此分块已下载的大小 Dictionary<Int64, Int64>^ blockDownloadedSize; #ifdef DEBUG Debug::Listeners->Add( gcnew TextWriterTraceListener( Console::Out ) ); Debug::AutoFlush = true; #endif bool Save();//保存配置信息 bool Load(String^ path);//加载配置信息 };
//TaskConfigFile.cpp #include "stdafx.h" #include "TaskConfigFile.h" TaskConfigFile::TaskConfigFile(): link(nullptr), fileName(nullptr), fileSize(0L), filePath(nullptr), blockSize(0L), sumDownloadedSize(0L), threadsSum(5) { blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum); } TaskConfigFile::TaskConfigFile(String^ str_link, Int64 file_size, short threads_sum): link(str_link), fileSize(file_size), threadsSum(threads_sum), sumDownloadedSize(0) { blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum); } TaskConfigFile::TaskConfigFile(String^ str_link, Int64 file_size): link(str_link), fileSize(file_size), threadsSum(5), sumDownloadedSize(0) { blockDownloadedSize = gcnew Dictionary<Int64, Int64>(threadsSum); } bool TaskConfigFile::Save() { String^ path = String::Concat(filePath, fileName, ".tmp"); Stream^ writeStream = gcnew FileStream(path, FileMode::Create, FileAccess::Write); if(writeStream == nullptr) { #ifdef DEBUG Diagnostics::Debug::WriteLine("文件路径错误!"); #endif return false; } BinaryWriter^ binaryWriter = gcnew BinaryWriter(writeStream, Encoding::ASCII); binaryWriter->Write(this->link); binaryWriter->Write(this->fileName); binaryWriter->Write(this->filePath); binaryWriter->Write(this->fileSize); binaryWriter->Write(this->blockSize); binaryWriter->Write(this->sumDownloadedSize); binaryWriter->Write(this->threadsSum); for each(KeyValuePair<Int64, Int64> pair in blockDownloadedSize) { binaryWriter->Write(pair.Key); binaryWriter->Write(pair.Value); } writeStream->Close(); binaryWriter->Close(); return true; } bool TaskConfigFile::Load(String^ path) { Stream^ readStream = gcnew FileStream(path, FileMode::Open, FileAccess::Read); if(readStream == nullptr) { #ifdef DEBUG Diagnostics::Debug::Indent(); Diagnostics::Debug::WriteLine("error: 打开文件失败!"); Diagnostics::Debug::WriteLine("Paht: {0}", path); Diagnostics::Debug::UnIndent(); #endif return false; } BinaryReader^ binaryReader = gcnew BinaryReader(readStream); try { link = binaryReader->ReadString(); fileName = binaryReader->ReadString(); filePath = binaryReader->ReadString(); fileSize = binaryReader->ReadInt64(); blockSize = binaryReader->ReadInt64(); sumDownloadedSize = binaryReader->ReadInt64(); threadsSum = binaryReader->ReadInt16(); for(int i = 0; i < threadsSum; ++i) { Int64 key = binaryReader->ReadInt64(); Int64 value = binaryReader->ReadInt64(); blockDownloadedSize->Add(key, value); } } catch(EndOfStreamException^ ex) { #ifdef DEBUG Diagnostics::Debug::Indent(); Diagnostics::Debug::WriteLine("The end of the stream is reached."); Diagnostics::Debug::WriteLine(ex->Message); Diagnostics::Debug::Unindent(); #endif readStream->Close(); binaryReader->Close(); return true; } return true; }
我将他们放在同一个文件就能编译通过。一旦分开就会出现链接错误:
这是因为.NET以程序集作为编译单元,每一个程序集里类的成员声明与定义必须在同一个namespace下,而这两个文件中并没有声明namespace,所以链接器找不到TaskConfigFile Class成员的实现代码。
必须将它们声明在同一个namspace中:
//TaskConfigFile.h namespace xxx { //.............. } //TaskConfigFile.cpp using namespace xxx;