First_layer
I have a win32 dll written in the VC ++ 6 service pack. 6. Call this DLL as FirstLayer. I do not have access to the source code of FirstLayer, but I need to call it from managed code. The problem is that FirstLayer makes heavy use of std :: vector and std :: string, and there is no way to combine these types into a C # application directly. The code for this layer below illustrates an example of what can be found in this DLL.
Second_Layer
The solution I can think of is to first create another win32 dll written in the VC ++ 6 Service Pack 6. Call this DLL as "SecondLayer". SecondLayer acts as a wrapper for FirstLayer, which basically converts STL types to user-defined types that are not STL types.
Third_Layer
I also created a VC ++ 2005 class library as a wrapper for SecondLayer. This shell does all the dirty work of converting an unmanaged second layer to managed code. Let us call this layer "third layer." The code for this layer, as shown below, is simplified to demonstrate an error, so it does not perform the aforementioned conversion.
Fourth_layer
, # 2005 ThirdLayer. # "FourthLayer".
FourthLayer (# 2005) → ThirdLayer (V++ 2005) → SecondLayer (V++ 6) → FirstLayer (V++ 6)
/ , :
: System.AccessViolationException: . , . SecondLayer.PassDataBackToCaller(SecondLayer, StdVectorWrapper *) Sample.ThirdLayer.PassDataBackToCaller() c:\project\ \test\sample\thirdlayer\thirdlayer.cpp: 22 FourthLayer.Program.Main(String [] args)
C:\Project\On Going Projects\test\Sample\FourthLayer\Program.cs: 14 *
, FourthLayer . , Windows XP , , Vista Windows 7, .
, . ? , ?
// Fourth_Layer ( # 2005)
class FourthLayer
{
static void Main(string[] args)
{
ThirdLayer thirdLayer = new ThirdLayer();
thirdLayer.PassDataBackToCaller();
}
}
//Third_Layer ( V++ 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 - (V++ 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 (V++ 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 (V++ 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 (V++ 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);
}