【问题标题】:P/Invoke Struct with Pointers, C++ from C#P/Invoke Struct with Pointers, C++ from C#
【发布时间】:2009-06-29 18:46:22
【问题描述】:

我正在尝试使用类似结构和函数的 C++ dll 调用

struct some_data{
  int size,degree,df,order;
  double *x,*y,lambda;
};

extern "C"{    
   __declspec(dllexport) double *some_func(some_data*);
}

来自 C#:

  [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct SOME_DATA
    {
        public int size;
        public int degree;
        public int df;
        public int order;
        public System.IntPtr x;
        public System.IntPtr y;
        public double lambda;
    }

    [System.Runtime.InteropServices.DllImportAttribute("mydll.dll",EntryPoint="some_func")]
    public static extern System.IntPtr some_func(ref SOME_DATA someData);

    public IntPtr some_funcCall(){
        double[] x = new double[] { 4, 4, 7, 7 };
        double[] y = new double[] { 2, 10, 4, 22 };

        SOME_DATA someData = new SOME_DATA();

        someData.x = Marshal.AllocHGlobal(x.Length * Marshal.SizeOf(typeof(double)));
        Marshal.Copy(x, 0, someData.x, x.Length);
        someData.y = Marshal.AllocHGlobal(y.Length * Marshal.SizeOf(typeof(double)));
        Marshal.Copy(y, 0, someData.y, y.Length);       
        someData.size = 50;
        someData.degree = 3;
        someData.df = 50;
        someData.order = 4;
        someData.lambda = 1;            

        return some_func(ref someData);
    }

我以为我已经非常接近了,但是当我运行它时,程序只是在 return 语句处退出。

任何想法我哪里出错了?

谢谢,

标记

【问题讨论】:

  • Opps,我在 C++ 中遇到了一个错误,它正在点击 exit()。现在我在 aaa.exe 中得到一个“System.AccessViolationException”类型的未处理异常附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。

标签: c# c++ pinvoke


【解决方案1】:

好像你忘记指定调用约定了:

[DllImport("mydll.dll", EntryPoint="some_func", CallingConvention=CallingConvention.Cdecl)]

【讨论】:

    【解决方案2】:

    你调试过 some_func 吗?尝试windbg该程序。或者使用 VS,但要确保捕获所有异常并启用混合调试。

    【讨论】:

    • 是的,终于回到这个调试。这是 C++ 中的错误。
    【解决方案3】:

    我会推荐一些超出 Ariel 建议的东西。

    1. some_func(ref someData) 语句移动到return 之前的行。
    2. 在该行之后调用Marshal.FreeHGlobal(否则会发生内存泄漏)。
    3. 如果order 等于数组长度,我会继续使用它。
    4. 您必须指定包装吗?也许你的包装没了?

    我可以建议的唯一其他想法是在您的结构中使用 double* 和/或使用 fixed 语句固定数组。

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 2010-11-18
      • 1970-01-01
      相关资源
      最近更新 更多