Класс экземпляра C # со статическими методами - использование методов по-разному между потоками - PullRequest
0 голосов
/ 04 декабря 2010

Здравствуйте, у меня есть этот код здесь:

Memory.OpenProcess(Processes[0].Id);
Hook.Apply(........);

Memory и Hook являются нестатическими классами, а openprocess и Apply являются статическими методами в этих классах.

Однако,проблема в том, что для каждого экземпляра моей памяти или хука я хочу, чтобы открывался отдельный процесс и применялся другой хук.

Я хочу сделать следующее:

Memory newMemory = new Memory();
newMemory.OpenProcess(processes[1].Id);

Hook newHook = new Hook();
newHook.Apply(....);

НоКонечно, я не могу сделать это, потому что методы являются статическими и не являются специфическими для каждого экземпляра.

Я не могу изменить статические методы, потому что эти методы приходят из библиотеки DLL, в которой у меня нет доступа к исходному коду.

Есть идеи?

** Редактировать: Я хочу сделать это, чтобы избежать повторного включения процесса каждый раз, когда появляется новый поток, работающий с другим процессом.

Ответы [ 4 ]

1 голос
/ 04 декабря 2010

Вы можете загрузить каждый поток в разные AppDomain , что даст вам различные статические методы.

Кроме того, ThreadStaticAttribute может быть полезным для вас. Не уверен, подходит ли он вам, но посмотрите.

Upd: больше информации об использовании доменов приложений. Предположим, что у вас есть сторонний класс Memory, определенный следующим образом. (И вы не можете изменить его, и он использует внутренние статические переменные)

// Cannot be changed
public class Memory
{
    static int StaticId;

    public static void OpenProcess(int id)
    {
        StaticId = id;
    }

    public static int GetOpenedId()
    {
        return StaticId;
    }
} 

Вы можете написать оболочку, производную от MarshalByRefObject (это важно):

class MemoryWrap : MarshalByRefObject
{
    public void OpenProcess(int id)
    {
        Memory.OpenProcess(id);
    }

    public int GetOpenedId()
    {
        return Memory.GetOpenedId();
    }
}

Таким образом, если вы создаете экземпляры MemoryWrap не по ключевому слову new, а с использованием AppDomain.CreateInstanceAndUnwrap в другом домене, каждый экземпляр будет иметь свой собственный статический контекст. Пример: * +1021 *

class Program
{
    static void Main(string[] args)
    {
        var type = typeof(MemoryWrap);

        var domain1 = AppDomain.CreateDomain("Domain 1");
        var memory1 = (MemoryWrap)domain1.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);

        var domain2 = AppDomain.CreateDomain("Domain 2");
        var memory2 = (MemoryWrap)domain2.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);

        memory1.OpenProcess(1);
        memory2.OpenProcess(2);

        Console.WriteLine(memory1.GetOpenedId());
        Console.WriteLine(memory2.GetOpenedId());

        Console.ReadLine();
    }
}

Будет напечатано:

1
2

PS: в этом примере я не делал очистку только для удобства чтения (выгрузка доменов с помощью AppDomain.Unload() и другие вещи). Не забудьте сделать это в своем коде. + Есть некоторый беспорядок с временем жизни объектов в другом домене, но это следующий уровень проблем)))

1 голос
/ 04 декабря 2010

Кажется, что вы не можете сделать это намеренно.Разработчик классов из dll, который вы потребляете, может явно хотеть избежать функциональности, которую вы пытаетесь достичь.

0 голосов
/ 04 декабря 2010

Смотрите, если авторы API делают это по какой-то причине, вам следует проконсультироваться с вашими авторами API по этой причине или если они могут предоставить вам что-то на уровне невосприимчивости.

НО, чтобы обойти вашу ситуацию, вы можете использовать метод, указанный выше The_Smallest.

, или вы можете использовать Reflection, как показано ниже

Memory m = Activator.CreateInstance("Your Dll Name", true) , here true stands for the calling of private constructor.

Но я не уверен, вам следует это сделать, вы сначала позвонитеписатель API, чтобы узнать причину этого.

0 голосов
/ 04 декабря 2010

Я не уверен, что полностью понимаю вопрос, но в любом случае постараюсь ответить.

Вы можете определить два новых класса:

public class MemoryInstance : Memory
{
  private var m_instanceProcessId;

  public MemoryInstance(var processId) : base()
  {
    m_instanceProcessId = processId;
  }

  public void OpenProcess()
  {
    Memory.OpenProcess(m_instanceProcessId);
  }
}

public class HookInstance: Hook
{
  private var m_hookId;

  public HookInstance(var hookId) : base()
  {
    m_hookId = hookId;
  }

  public void Apply()
  {
    Hook.Apply(m_hookId);
  }
}

Тогда в своем коде вы можете позвонить:

public static void Main(String[] args)
{
  MemoryInstance newMemory = new MemoryInstance(processes[1].Id);
  HookInstance newHook = new HookInstance(hookId);

  newMemory.OpenProcess();
  newHook.Apply();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...