C++/CLI에서 std::Vector<>::iterator를 .NET 인터페이스로 변환
-
01-07-2019 - |
문제
다음과 같은 메서드가 있는 네이티브 C++ 클래스를 래핑합니다.
class Native
{
public:
class Local
{
std::string m_Str;
int m_Int;
};
typedef std::vector<Local> LocalVec;
typedef LocalVec::iterator LocalIter;
LocalIter BeginLocals();
LocalIter EndLocals();
private:
LocalVec m_Locals;
};
1) 이와 동일한 종류의 인터페이스를 나타내는 ".NET 방식"은 무엇입니까?배열<>을 반환하는 단일 메서드?BeginLocals() 및 EndLocals()를 구현할 수 있도록 array<> 일반에 반복자가 있습니까?
2) Local을 다음으로 선언해야합니까? 값 구조체 .NET 래퍼에서?
저는 래핑된 클래스를 .NET 방식으로 표현하고 싶지만 관리되는 세계는 처음 접합니다. 이러한 유형의 정보는 Google에 실망스럽습니다.
해결책
반복자는 정확히 ".net 방식"으로 번역할 수는 없지만 대략 IEnumerable < T > 및 IEnumerator < T >로 대체됩니다.
보다는
vector<int> a_vector;
vector<int>::iterator a_iterator;
for(int i= 0; i < 100; i++)
{
a_vector.push_back(i);
}
int total = 0;
a_iterator = a_vector.begin();
while( a_iterator != a_vector.end() ) {
total += *a_iterator;
a_iterator++;
}
당신은 볼 것입니다 (C#에서)
List<int> a_list = new List<int>();
for(int i=0; i < 100; i++)
{
a_list.Add(i);
}
int total = 0;
foreach( int item in a_list)
{
total += item;
}
또는 더 명시적으로(foreach 구문 설탕 뒤에 IEnumerator를 숨기지 않고):
List<int> a_list = new List<int>();
for (int i = 0; i < 100; i++)
{
a_list.Add(i);
}
int total = 0;
IEnumerator<int> a_enumerator = a_list.GetEnumerator();
while (a_enumerator.MoveNext())
{
total += a_enumerator.Current;
}
보시다시피 foreach는 .net 열거자를 숨깁니다.
따라서 실제로 ".net 방식"은 사람들이 스스로 List< Local > 항목을 만들 수 있도록 허용하는 것입니다.반복을 제어하거나 컬렉션을 좀 더 맞춤화하려면 컬렉션에서 IEnumerable< T > 및/또는 ICollection< T > 인터페이스도 구현하도록 하세요.
C#으로의 거의 직접적인 번역은 여러분이 가정한 것과 거의 같습니다.
public class Native
{
public class Local
{
public string m_str;
public int m_int;
}
private List<Local> m_Locals = new List<Local>();
public List<Local> Locals
{
get{ return m_Locals;}
}
}
그러면 사용자는 다음을 수행할 수 있습니다.
foreach( Local item in someNative.Locals)
{
...
}
다른 팁
@Phillip - 감사합니다. 귀하의 답변 덕분에 제가 올바른 방향으로 나아갈 수 있게 되었습니다.
코드를 보고 Nish의 책을 조금 더 읽은 후 C++/CLI 실행, 관리되는 힙의 Local 인스턴스에 const 추적 핸들을 반환하는 인덱싱된 속성을 사용하는 것이 아마도 최선의 접근 방식일 것입니다.결국 다음과 비슷한 것을 구현했습니다.
public ref class Managed
{
public:
ref class Local
{
String^ m_Str;
int m_Int;
};
property const Local^ Locals[int]
{
const Local^ get(int Index)
{
// error checking here...
return m_Locals[Index];
}
};
private:
List<Local^> m_Locals;
};