0

I downloaded a NuGet package called Process.NET, and I try to use the Read() method from the IMemory interface in my main() function. I implemented it as in the GIT tutorial, but I am unable to create an instance of ProcessMemory like this:

ProcessMemory memory = new ProcessMemory();

I get this error:

"Unable to create instance of the abstract class or interface 'ProcessMemory'. "

I found some threads about that, but nothing could help me yet. Here is my Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Process.NET.Memory;
using Process.NET.Native.Types;

namespace MemoryHacker
{
    class Program
    {
        static void Main(string[] args)
        {

            ProcessMemory memory = new ProcessMemory();

        }
    }

    //Class with Read() function
    public abstract class ProcessMemory : IMemory
    {
        protected readonly SafeMemoryHandle Handle;

        protected ProcessMemory(SafeMemoryHandle handle)
        {
            Handle = handle;
        }

        public abstract byte[] Read(IntPtr intPtr, int length);

        public string Read(IntPtr intPtr, Encoding encoding, int maxLength)
        {
            var buffer = Read(intPtr, maxLength);
            var ret = encoding.GetString(buffer);
            if (ret.IndexOf('\0') != -1)
                ret = ret.Remove(ret.IndexOf('\0'));
            return ret;
        }

        public abstract T Read<T>(IntPtr intPtr);

        public T[] Read<T>(IntPtr intPtr, int length)
        {
            var buffer = new T[length];
            for (var i = 0; i < buffer.Length; i++)
                buffer[i] = Read<T>(intPtr);
            return buffer;
        }

        public abstract int Write(IntPtr intPtr, byte[] bytesToWrite);

        public void Write(IntPtr intPtr, string stringToWrite, Encoding encoding)
        {
            if (stringToWrite[stringToWrite.Length - 1] != '\0')
                stringToWrite += '\0';
            var bytes = encoding.GetBytes(stringToWrite);
            Write(intPtr, bytes);
        }


        public void Write<T>(IntPtr intPtr, T[] values)
        {
            foreach (var value in values)
                Write(intPtr, value);
        }

        public abstract void Write<T>(IntPtr intPtr, T value);
    }

}

EDIT: Okay, the thing with the instantiating is clear now. But I am still getting an error:

"No argument was specified that corresponds to the formal handle parameter of ProcessMemory.ProcessMemory (SafeMemoryHandle)."

any ideas, while watching the code above?

EDIT2: All you need to solve this problem is said in the answers below. Just a little hint, if you are using Visual Studio, then rightclick the new class, and click on implement. It writes a lot of stuff for ya!

  • 3
    You need to create a new class that derives from the `ProcessMemory` class. – itsme86 Apr 16 '19 at 20:39
  • You cannot instantiate an abstract class. Only the implementation can be instantiated. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract – Sebastian Siemens Apr 16 '19 at 20:43
  • You've got to use one of the derived classes like `LocalProcessMemory`. – tukaef Apr 16 '19 at 20:51
  • Thanks for the answers guys, the documentation was a great help. I decided to override the methods in a new class. But still getting an error ^^ But this time its: "No argument was specified that corresponds to the formal handle parameter of ProcessMemory.ProcessMemory (SafeMemoryHandle)." –  Apr 16 '19 at 21:07
  • @d219 I already read that before, and I tried it like this, but didnt helped me. –  Apr 16 '19 at 21:14
  • Ah - yeah reading it further that answer relates more to interfaces, will removed the suggestion. – d219 Apr 16 '19 at 21:19
  • 3
    Possible duplicate of [Cannot create an instance of the abstract class or interface](https://stackoverflow.com/questions/6611412/cannot-create-an-instance-of-the-abstract-class-or-interface) – EJoshuaS - Stand with Ukraine Apr 16 '19 at 23:51

4 Answers4

2

I'm not familiar with the package, and it is not clear to me what you are trying to achieve, so I don't really know how I can help you, but I can tell you this:

An abstract class is not supposed to be instantiated.

you'll either have to remove the abstract keyword, or make your own class, that implements the abstract class like this:

public class MyProcessMemory : ProcessMemory
{
    public override byte[] Read(IntPtr intPtr, int length)
    {
        throw new NotImplementedException();
    }

    public override T Read<T>(IntPtr intPtr)
    {
        throw new NotImplementedException();
    }

    public override int Write(IntPtr intPtr, byte[] bytesToWrite)
    {
        throw new NotImplementedException();
    }

    public override void Write<T>(IntPtr intPtr, T value)
    {
        throw new NotImplementedException();
    }
}

In either case you'll have to come up with your own implementation of the abstract functions. Hope this helps

pieterVdM
  • 34
  • 5
  • Thank you, I learned a lot. I was never really sure about abstract class and interface. Unfortunaly, I tried it and get an error again. This time its "No argument was specified that corresponds to the formal handle parameter of ProcessMemory.ProcessMemory (SafeMemoryHandle)." - Any suggestions? –  Apr 16 '19 at 21:05
  • @Bush_Did_911 you need to satisfy the constructor in the abstract class. It's expecting a `SafeMemoryHandle` argument. Something like this `MyProcessMemory(SafeMemoryHandle handle) : base(handle) { }` would work – PC Luddite Apr 16 '19 at 21:28
0

You can not use abstract classes directly. You can use those when creating new class that derives from those

Jack
  • 167
  • 1
  • 7
0

You cannot instantiate an abstract class. The purpose of an abstract class is to provide a common interface for deriving classes. It's not explicitly necessary for an abstract class to provide an implementation for any method (notice the lack of body for the methods marked abstract) because it's expected that the child classes provide the bulk of the implementation. Read the documentation to see which child class is best suited for your needs and instantiate that.

PC Luddite
  • 5,883
  • 6
  • 23
  • 39
0

You can not instantiate an abstract class directly, you need to create another class that implements it and provides a complete implementation by completing any methods marked as abstract in the base class. In your case this is:

byte[] Read(IntPtr intPtr, int length)

T Read<T>(IntPtr intPtr)

int Write(IntPtr intPtr, byte[] bytesToWrite)

void Write<T>(IntPtr intPtr, T value)

The following link may aid you in understanding more https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract. Relating to classes it states in that:

The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.

and

Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class.

d219
  • 2,707
  • 5
  • 31
  • 36
  • Thanks man! If I am right, then the abstract class is like a template for another class, isn't it?? –  Apr 16 '19 at 21:09
  • Yes that's right, it may provide some methods but you need to fill in the rest. – d219 Apr 16 '19 at 21:10
  • Okay, and an interface is a template with declared methods, but they are actually empty and can be filled with code in a class, is this right aswell? –  Apr 16 '19 at 21:12
  • Yes an interface is entirely empty, you can implement multiple interfaces but only inherit from one class (be that abstract or 'normal') – d219 Apr 16 '19 at 21:13
  • No problem, this may help as well (has a lot of up votes!) https://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo?rq=1 – d219 Apr 16 '19 at 21:22