First_Layer挑戰運行時錯誤從託管代碼調用本機代碼時
我已經寫在VC++ 6服務包6.一個Win32 DLL讓我們把這個DLL作爲FirstLayer。我沒有訪問FirstLayer的源代碼,但我需要從管理的 代碼中調用它。問題是FirstLayer大量使用std :: vector和std :: string,並且沒有辦法將這些類型直接封裝到C#應用程序中。下面這個圖層的代碼舉例說明了在這個dll中可以找到什麼。
Second_Layer
,我能想到的是先創建寫在VC++ 6.0的Service Pack 6另一個win32的DLL讓我們把這個DLL作爲 「SecondLayer」 的解決方案。 SecondLayer充當FirstLayer的包裝器,它基本上將STL類型轉換爲定製的非STL類類型。
Third_Layer
我還創建了一個VC++ 2005類庫作爲SecondLayer的包裝。這個包裝器完成將非託管SecondLayer轉換爲託管代碼的所有骯髒工作。我們把這個圖層稱爲「ThirdLayer」。如下所示的該層的代碼被簡化以顯示該錯誤,因此它不執行上述轉換。
Fourth_Layer
更有甚者,我創建了一個C#2005控制檯應用程序調用ThirdLayer。我們將這個C#控制檯應用程序稱爲「FourthLayer」。
呼叫序列總結
FourthLayer(C#2005) - > ThirdLayer(VC++ 2005) - > SecondLayer(VC 6) - > FirstLayer(VC 6)
的運行時錯誤
下面的代碼編譯/建立一個沒有錯誤,但我得到以下運行時錯誤:
未處理的異常:System.AccessViolatio nException:嘗試讀取或寫入受保護的內存。這通常表明其他內存已損壞。在SecondLayer.PassDataBackToCaller(SecondLayer,StdVectorWrapper *)處打開項目\ test \ sample \ thirdlayer \ thirdlayer.cpp中的Sample.ThirdLayer.PassDataBackToCaller()在c:\ project \中:第22行位於FourthLayer.Program.Main(String [ ] args)in C:\ Project \ On Projects \ test \ Sample \ FourthLayer \ Program.cs:line 14 *
當在不同的操作系統上執行FourthLayer應用程序時,不需要出現此錯誤。例如,對於Windows XP,沒有錯誤,但對於Vista和Windows 7等其他操作系統,則會顯示錯誤。
我不明白是什麼造成了這一點。有任何想法嗎?我怎樣才能修改代碼來糾正這個問題?
// Fourth_Layer(C#2005控制檯應用程序)
class FourthLayer
{
static void Main(string[] args)
{
ThirdLayer thirdLayer = new ThirdLayer();
thirdLayer.PassDataBackToCaller();
}
}
// Third_Layer(VC++ 2005類庫)
public ref class ThirdLayer
{
private:
SecondLayer *_secondLayer;
public:
ThirdLayer();
~ThirdLayer();
void PassDataBackToCaller();
};
ThirdLayer::ThirdLayer()
{
_secondLayer = new SecondLayer();
}
ThirdLayer::~ThirdLayer()
{
delete _secondLayer;
}
void ThirdLayer::PassDataBackToCaller()
{
StdVectorWrapper v;
_secondLayer->PassDataBackToCaller(v);
for (int i=0; i<v.GetSize(); i++)
{
StdStringWrapper s = v.GetNext();
std::cout << s.CStr() << std::endl;
}
}
// Second_Layer - 主類(VC++ 6 win32 dll)
class SECOND_LAYER_API SecondLayer
{
private:
FirstLayer *_firstLayer;
public:
SecondLayer();
~SecondLayer();
void PassDataBackToCaller(StdVectorWrapper &toCaller);
private:
void ConvertToStdVectorWrapper(
const std::vector<std::string> &in, StdVectorWrapper &out);
};
SecondLayer::SecondLayer() : _firstLayer(new FirstLayer())
{
}
SecondLayer::~SecondLayer()
{
delete _firstLayer;
}
void SecondLayer::PassDataBackToCaller(StdVectorWrapper &toCaller)
{
std::vector<std::string> v;
_firstLayer->PassDataBackToCaller(v);
ConvertToStdVectorWrapper(v, toCaller);
}
void SecondLayer::ConvertToStdVectorWrapper(
const std::vector<std::string> &in, StdVectorWrapper &out)
{
for (std::vector<std::string>::const_iterator it=in.begin(); it!=in.end(); ++it)
{
StdStringWrapper s((*it).c_str());
out.Add(s);
}
}
// Second_Layer - StdVectorWrapper類(VC 6的Win32 DLL)
class SECOND_LAYER_API StdVectorWrapper
{
private:
std::vector<StdStringWrapper> _items;
int index;
public:
StdVectorWrapper();
void Add(const StdStringWrapper& item);
int GetSize() const;
StdStringWrapper& GetNext();
};
StdVectorWrapper::StdVectorWrapper()
{
index = 0;
}
void StdVectorWrapper::Add(const StdStringWrapper &item)
{
_items.insert(_items.end(),item);
}
int StdVectorWrapper::GetSize() const
{
return _items.size();
}
StdStringWrapper& StdVectorWrapper::GetNext()
{
return _items[index++];
}
// Second_Layer - StdStringWrapper類(VC 6的Win32 DLL)
class SECOND_LAYER_API StdStringWrapper
{
private:
std::string _s;
public:
StdStringWrapper();
StdStringWrapper(const char *s);
void Append(const char *s);
const char* CStr() const;
};
StdStringWrapper::StdStringWrapper()
{
}
StdStringWrapper::StdStringWrapper(const char *s)
{
_s.append(s);
}
void StdStringWrapper::Append(const char *s)
{
_s.append(s);
}
const char* StdStringWrapper::CStr() const
{
return _s.c_str();
}
// First_Layer(VC++ 6 win32 dll)
class FIRST_LAYER_API FirstLayer
{
public:
void PassDataBackToCaller(std::vector<std::string> &toCaller);
};
void FirstLayer::PassDataBackToCaller(std::vector<std::string> &toCaller)
{
std::string a, b;
a.append("Test string 1");
b.append("Test string 2");
toCaller.insert(toCaller.begin(),a);
toCaller.insert(toCaller.begin(),b);
}