简体   繁体   中英

Call C structure data from C#

I have make a dll from dev c++.and I want to call the function. the dev c++ code like this :

//the head file
struct sAdd
{
int* aarr;
int* barr;
int length;
};
DLLIMPORT int AddStruct (struct sAdd*);
//the c file
 DLLIMPORT int AddStruct (struct sAdd* sadd)
{//sum the aarr and the barr and return the result.
          int sum=0;

          int* aarr=sadd->aarr;
          int* barr=sadd->barr;
         int numArr=sadd->length;      
          int i;
          for(i=0;i<numArr;i++)
          sum+=*(aarr+i);
          i=0;
          for(i=0;i<numArr;i++)
          sum+=*(barr+i);

          return sum;       
}

In order to call the AddStruct function,I need to define a struct first.

public struct sAdd
{
    public int[] a;
    public int[] b;
    public int length;
}
  [DllImport("DllMain.dll", CallingConvention = CallingConvention.Cdecl)]
  public static extern int AddStruct(ref sAdd sadd);

the code to call the AddStruct function is like this:

    sAdd sadd = new sAdd();
    sadd.a = new int[4] { 1, 2, 3 ,4};
    sadd.b = new int[4] { 1, 2, 3 ,4};
    sadd.length=4;
    Console.WriteLine("sAdd:" + AddStruct(ref sadd).ToString());

the result should be 20,but I get a 37109984 or some other big number. So ,I am not sure how to change the code to get a right reusult.Maybe I need to use the IntPtr or other ways??thanks .

At last,I deal with the problem.Just modify the code in c#.

  [StructLayout(LayoutKind.Sequential)]
  public struct sAdd
  {
      public IntPtr a;
      public IntPtr b;
     public int length;
  };
            sAdd sadd = new sAdd();
            int[] a = new int[4] { 1, 2, 3 ,4};
             int[] b = new int[4] { 1, 2, 3 ,4};
            sadd.length = 4;
            sadd.a = Marshal.UnsafeAddrOfPinnedArrayElement(a, 0);
            sadd.b = Marshal.UnsafeAddrOfPinnedArrayElement(b, 0);
            Console.WriteLine("sAdd:" + DllMainWrapper.AddStruct(ref sadd).ToString());

Your C code is broken.

You cannot compute the length of an array using sizeof when all you have is a pointer to the first element. You can only do so when you have a "real" array declaration in scope.

So this:

int* aarr=sadd->aarr;
int* barr=sadd->barr;
int numAarr=sizeof(aarr)/sizeof(int);
int numBarr=sizeof(barr)/sizeof(int);         

is broken, numArr will be a constant value (1 if your pointer size is the same as your integer size, otherwise probably 2 on a 64-bit system with 32-bit int ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM