【问题标题】:Call C structure data from C#从 C# 调用 C 结构数据
【发布时间】:2013-04-27 16:52:13
【问题描述】:

我从 dev c++ 创建了一个 dll。我想调用该函数。 dev c++ 代码是这样的:

//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;       
}

为了调用AddStruct函数,我需要先定义一个结构体。

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);

调用AddStruct函数的代码如下:

    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());

结果应该是 20,但我得到了 37109984 或其他一些大数字。 所以,我不确定如何更改代码以获得正确的结果。也许我需要使用 IntPtr 或其他方式?谢谢。

最后,我处理了这个问题。只需修改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());

【问题讨论】:

    标签: c# c dll call dev-c++


    【解决方案1】:

    您的 C 代码已损坏。

    当您只有一个指向第一个元素的指针时,您无法使用sizeof 计算数组的长度。只有在作用域中有“真实”数组声明时才能这样做。

    所以这个:

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

    已损坏,numArr 将是一个常量值(如果指针大小与整数大小相同,则为 1,否则在具有 32 位 int 的 64 位系统上可能为 2)。

    【讨论】:

    • 感谢回复。为了测试错误。我已经更改了C代码和c#代码。但它仍然无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多