Преобразование шаблона C++ в C#

У меня есть шаблон в проекте 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);

Как вы думаете, что означает эта ошибка?

mjwills 27.10.2018 04:18

который не может преобразовать тип, но тип уже правильный, Int64

CerraossoUC 27.10.2018 04:19

Что такое pObfuscationMgr (на обоих языках)?

1201ProgramAlarm 27.10.2018 04:30

Преобразование кода C++, который активно использует шаблоны и подобные небезопасные / непроверенные преобразования, в C#, вероятно, будет довольно чревато - почти наверняка есть более подходящие способы добиться того же. Сколько это кода?

Dylan Nicholson 27.10.2018 04:37

pObfuscationMgr - это тип int64, код не очень большой 284 строки

CerraossoUC 27.10.2018 04:40

Вы должны понимать, что template и generic - две очень разные вещи, хотя синтаксис кажется чем-то похожим. Так что не пытайтесь делать дословный перевод, а постарайтесь найти, как вы могли бы реализовать эту функциональность в C# в основном с нуля.

Phil1970 27.10.2018 06:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
206
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина ошибки в том, что вы указываете компилятору интерпретировать позицию в памяти как объект 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#, то есть сделать настоящий перевод.

Надеюсь, это (как-то) поможет.

Другие вопросы по теме