У меня есть шаблон в проекте C++, и я хочу сейчас перевести код на C#, и я получаю некоторые ошибки в шаблоне C#.
В C++
template<typename T>
struct pares
{
DWORD64 first;
T* second;
};
template<typename T>
struct hash_node
{
pares<T> mValue;
hash_node<T>* mpNext;
};
template<typename T>
struct hashtable
{
DWORD64 vtable;
hash_node<T>** mpBucketArray;
unsigned int mnBucketCount;
unsigned int mnElementCount;
//...
};
template<typename T>
struct hashtable_iterator
{
hash_node<T>* mpNode;
hash_node<T>** mpBucket;
};
В C#
public class pair<T>
{
public Int64 first;
public T second;
}
public class hash_node<T>
{
public pair<T> mValue = new pair<T>();
public hash_node<T> mpNext;
}
public class hashtable<T>
{
public Int64 vtable;
public hash_node<T>[] mpBucketArray;
public int mnBucketCount;
public int mnElementCount;
}
public class hashtable_iterator<T>
{
public hash_node<T> mpNode;
public hash_node<T> mpBucket;
}
Внутри функции в проекте C++ у меня есть эта строка, без ошибок:
hashtable<DWORD64>* table = (hashtable<DWORD64>*)(pObfuscationMgr + 8);
Но в C# возникает ошибка:
Cannot convert type 'long' to 'hashtable'
hashtable<Int64> table = (hashtable<Int64>)(pObfuscationMgr + 8);
который не может преобразовать тип, но тип уже правильный, Int64
Что такое pObfuscationMgr
(на обоих языках)?
Преобразование кода C++, который активно использует шаблоны и подобные небезопасные / непроверенные преобразования, в C#, вероятно, будет довольно чревато - почти наверняка есть более подходящие способы добиться того же. Сколько это кода?
pObfuscationMgr - это тип int64, код не очень большой 284 строки
Вы должны понимать, что template
и generic
- две очень разные вещи, хотя синтаксис кажется чем-то похожим. Так что не пытайтесь делать дословный перевод, а постарайтесь найти, как вы могли бы реализовать эту функциональность в C# в основном с нуля.
Причина ошибки в том, что вы указываете компилятору интерпретировать позицию в памяти как объект hashtable<>
. Это работает в C++, потому что у вас есть инструмент для этого: указатели. Указатель - это просто позиция в памяти со связанным типом.
У вас есть блок памяти, на который указывает pObfuscationMgr
, и вы намереваетесь создать указатель на hashtable<>
, и таким образом понимать содержимое в этой позиции памяти (плюс восемь) как hashtable<>
.
Если вы сделаете дословный перевод на C#:
hashtable<Int64> table = (hashtable<Int64>)(pObfuscationMgr + 8);
Указатели теряются при этом переводе, потому что в C# нет указателей. Итак, теперь pObfuscationMgr
теперь просто long
, и, следовательно, ошибка компилятора: вы не можете преобразовать long
в hashtable<>
.
Например, вы можете сделать это на C или C++:
void foo()
{
char buffer[1024];
int * ptr1 = (int *) &buffer;
int * ptr2 = (int *) ( &buffer + 8 );
*ptr1 = 40;
*ptr1 += 2;
*ptr2 = 5;
*ptr2 *= 2;
printf( "%d\n", *ptr1 );
printf( "%d\n", *ptr2 );
}
В приведенном выше коде вы создаете область буферизации в стеке в форме массива char
. Затем вы создаете указатели ptr1
и ptr2
и заставляете их указывать на начало этой области и начало этой области плюс восемь. Затем вы можете управлять обоими указателями, как если бы они указывали на реальные переменные. Это более или менее похоже на то, что делает исходный код.
Вы не добьетесь успеха, сделав дословный перевод кода C++ на C#. Конечно, такой перевод возможен, но при наличии глубоких знаний о памяти в C++ и о том, как представить это в C#, то есть сделать настоящий перевод.
Надеюсь, это (как-то) поможет.
Как вы думаете, что означает эта ошибка?