12

I have 2 functions within a class and getting error on the call for ParseBits() function i.e. "int num_elements = ParseBits(bits, buffer);" because of the "buffer" arguement I am passing "public int ParseBits(string bits, int* buffer)":

Function 1:

public float AssignFitness(string bits, int target_value)
        {

   //holds decimal values of gene sequence
   int[] buffer = new int[(VM_Placement.AlgorithmParameters.chromo_length / VM_Placement.AlgorithmParameters.gene_length)];

   int num_elements = ParseBits(bits, buffer);

   // ok, we have a buffer filled with valid values of: operator - number - operator - number..
   // now we calculate what this represents.
   float result = 0.0f;

   for (int i=0; i < num_elements-1; i+=2)
   {
      switch (buffer[i])
      {
         case 10:

            result += buffer[i+1];
            break;

         case 11:

            result -= buffer[i+1];
            break;

         case 12:

            result *= buffer[i+1];
            break;

         case 13:

            result /= buffer[i+1];
            break;

      }//end switch

   }

   // Now we calculate the fitness. First check to see if a solution has been found
   // and assign an arbitarily high fitness score if this is so.

   if (result == (float)target_value)

      return 999.0f;

   else

      return 1/(float)fabs((double)(target_value - result));
   //   return result;
}

Function 2:

public int ParseBits(string bits, int* buffer)
        {

            //counter for buffer position
            int cBuff = 0;

            // step through bits a gene at a time until end and store decimal values
            // of valid operators and numbers. Don't forget we are looking for operator - 
            // number - operator - number and so on... We ignore the unused genes 1111
            // and 1110

            //flag to determine if we are looking for an operator or a number
            bool bOperator = true;

            //storage for decimal value of currently tested gene
            int this_gene = 0;

            for (int i = 0; i < VM_Placement.AlgorithmParameters.chromo_length; i += VM_Placement.AlgorithmParameters.gene_length)
            {
                //convert the current gene to decimal
                this_gene = BinToDec(bits.Substring(i, VM_Placement.AlgorithmParameters.gene_length));

                //find a gene which represents an operator
                if (bOperator)
                {
                    if ((this_gene < 10) || (this_gene > 13))

                        continue;

                    else
                    {
                        bOperator = false;
                        buffer[cBuff++] = this_gene;
                        continue;
                    }
                }

                //find a gene which represents a number
                else
                {
                    if (this_gene > 9)

                        continue;

                    else
                    {
                        bOperator = true;
                        buffer[cBuff++] = this_gene;
                        continue;
                    }
                }

            }//next gene

            //   now we have to run through buffer to see if a possible divide by zero
            //   is included and delete it. (ie a '/' followed by a '0'). We take an easy
            //   way out here and just change the '/' to a '+'. This will not effect the 
            //   evolution of the solution
            for (int i = 0; i < cBuff; i++)
            {
                if ((buffer[i] == 13) && (buffer[i + 1] == 0))

                    buffer[i] = 10;
            }

            return cBuff;
        }

I am getting 2 errors for this functions on the highlighted lines:

Error 1: The best overloaded method match for 'VM_Placement.Program.ParseBits(string, int*)' has some invalid arguments

Error 2: Pointers and fixed size buffers may only be used in an unsafe context
user1277070
  • 765
  • 3
  • 10
  • 15
  • So what's your question? why you get the errors? what you can do to avoid them? why you can't use pointers in managed code or something different? (knowing exactly what you what help with makes it easier to help you than if we have to guess, we might be right and we might not) – Rune FS Apr 22 '12 at 16:35
  • What can I do to avoid them... I guess I am passing the arguments in ParseBits() function in an incorrect manner and hence I am getting one more error "Argument 2: cannot convert from 'int[]' to 'int*'" – user1277070 Apr 22 '12 at 16:58
  • Why are you using pointers in the first place? – harold Apr 22 '12 at 17:34

3 Answers3

26

You need to enclose your function using raw pointers in an unsafe block.

unsafe 
{
 //your code
}
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • and how to call that function then? making the function unsafe removed the "Pointers and fixed size buffers may only be used in an unsafe context" error, but I am still getting "The best overloaded method match for 'VM_Placement.Program.ParseBits(string, int*)' has some invalid arguments" on that function call. – user1277070 Apr 22 '12 at 16:35
  • I would say you'd also make the call site of your function `unsafe` since it also requires pointers. – Tony The Lion Apr 22 '12 at 16:41
  • Nopes didn't work out... I guess its because of the kind of arguements I am passing... I am getting one more error for the argument pass while calling ParseBits() "Argument 2: cannot convert from 'int[]' to 'int*'" – user1277070 Apr 22 '12 at 16:57
  • 2
    @user1277070 in C# an T[] (in your case int[]) is not a T* which is why you get the error – Rune FS Apr 22 '12 at 17:42
9

I had the same problem, but it wasn't solved by any of the other answers up here. I kept getting different errors.

Whatever functions use unsafe code simply need to be declared with the "unsafe" keyword.
For example:

static unsafe void myFunction(int* myInt, float* myFloat)  
{
    // Function definition
}

Personally, I was trying to do this when making a wrapper class.
For those interested, it ended up looking something like this:

using System.Runtime.InteropServices;

namespace myNamespace
{
    public class myClass
    {
        [DllImport("myLib.so", EntryPoint = "myFunction")]
        public static extern unsafe void myFunction(float* var1, float* var2);
    }
}

Theres a lot of great information in the MSDN "Unsafe Code Tutorial":
https://msdn.microsoft.com/en-us/library/aa288474(v=vs.71).aspx

It's probably worth a read, I found it quite useful.

MD-7
  • 191
  • 1
  • 3
  • 4
    Note that using the `unsafe` declaration also requires to check the `"Allow unsafe code"` option in the project's properties (under the `Build` tab) – Yoav Feuerstein Oct 10 '19 at 13:14
6

Perhaps I've missed it, but you don't appear to be doing anything that actually requires the use of a int*. Why not simply pass it an int array and change the ParseBits function signature to:

public int ParseBits(string bits, int[] buffer)

and remove the unsafe{ ... } blocks altogether.

Iridium
  • 23,323
  • 6
  • 52
  • 74