手头已经有了一份c写的dll(含源代码),共暴露出来四个函数,现在想用C#调用它们。但是参数很复杂,是struct指针,所以我用C#定义了struct,作为参数传进去。可是运行的时候,老是说堆栈被破坏,或是访问非法内存地址。请大家帮帮忙,看看应该怎么写,才能给C#正确调用,分不够,我再加,谢谢大家了^_^。下面是dll中的函数原型:
_declspec(dllexport) short InitEncode( iLBC_Enc_Inst_t *iLBCenc_inst,  int mode );
_declspec(dllexport) short InitDecode( iLBC_Dec_Inst_t *iLBCdec_inst,  int mode, int use_enhancer );
_declspec(dllexport)  short encode( iLBC_Enc_Inst_t *iLBCenc_inst, short *encoded_data, short *data );
_declspec(dllexport) short decode( iLBC_Dec_Inst_t *iLBCdec_inst, short *decoded_data, short *encoded_data, short mode );
参数用到的结构的原型是(其中用到的全大写的是宏定义,都是些整数,就不列出来了):
typedef struct iLBC_Enc_Inst_t_ {       /* flag for frame size mode */
       int mode;       /* basic parameters for different frame sizes */
       int blockl;
       int nsub;
       int nasub;
       int no_of_bytes, no_of_words;
       int lpc_n;
       int state_short_len;
       const iLBC_ULP_Inst_t *ULP_inst;       /* analysis filter state */
       float anaMem[LPC_FILTERORDER];       /* old lsf parameters for interpolation */
       float lsfold[LPC_FILTERORDER];
       float lsfdeqold[LPC_FILTERORDER];       /* signal buffer for LP analysis */
       float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];       /* state of input HP filter */
       float hpimem[4];   } iLBC_Enc_Inst_t;typedef struct iLBC_Dec_Inst_t_ {       /* flag for frame size mode */
       int mode;       /* basic parameters for different frame sizes */
       int blockl;
       int nsub;
       int nasub;
       int no_of_bytes, no_of_words;
       int lpc_n;
       int state_short_len;
       const iLBC_ULP_Inst_t *ULP_inst;       /* synthesis filter state */
       float syntMem[LPC_FILTERORDER];       /* old LSF for interpolation */
float lsfdeqold[LPC_FILTERORDER];       /* pitch lag estimated in enhancer and used in PLC */
       int last_lag;       /* PLC state information */
       int prevLag, consPLICount, prevPLI, prev_enh_pl;
       float prevLpc[LPC_FILTERORDER+1];
       float prevResidual[NSUB_MAX*SUBL];
       float per;
       unsigned long seed;       /* previous synthesis filter parameters */
       float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];       /* state of output HP filter */
       float hpomem[4];       /* enhancer state information */
       int use_enhancer;
       float enh_buf[ENH_BUFL];
       float enh_period[ENH_NBLOCKS_TOT];   } iLBC_Dec_Inst_t;   typedef struct iLBC_ULP_Inst_t_ {
       int lsf_bits[6][ULP_CLASSES+2];
       int start_bits[ULP_CLASSES+2];
       int startfirst_bits[ULP_CLASSES+2];
       int scale_bits[ULP_CLASSES+2];
       int state_bits[ULP_CLASSES+2];
       int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2];
       int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2];
       int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
       int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
   } iLBC_ULP_Inst_t;

解决方案 »

  1.   

    这是我写的一个定义,看看那里错了
    [StructLayout(LayoutKind.Sequential)]
            public struct iLBC_ULP_Inst_t
            {
                public int[,] lsf_bits; // = new int[6, ULP_CLASSES + 2];
                public int[] start_bits;// = new int[ULP_CLASSES + 2];
                public int[] startfirst_bits;// = new int[ULP_CLASSES + 2];
                public int[] scale_bits; //= new int[ULP_CLASSES + 2];
                public int[] state_bits; //= new int[ULP_CLASSES + 2];            public int[,] extra_cb_index;// = new int[CB_NSTAGES, ULP_CLASSES + 2];
                public int[,] extra_cb_gain;// = new int[CB_NSTAGES, ULP_CLASSES + 2];
                public int[, ,] cb_index; //= new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];
                public int[, ,] cb_gain;// = new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];            public iLBC_ULP_Inst_t(bool init)
                {
                    lsf_bits = new int[6, ULP_CLASSES + 2];
                    start_bits = new int[ULP_CLASSES + 2];
                    startfirst_bits = new int[ULP_CLASSES + 2];
                    scale_bits = new int[ULP_CLASSES + 2];
                    state_bits = new int[ULP_CLASSES + 2];                extra_cb_index = new int[CB_NSTAGES, ULP_CLASSES + 2];
                    extra_cb_gain = new int[CB_NSTAGES, ULP_CLASSES + 2];
                    cb_index = new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];
                    cb_gain = new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];
                }
            };
      

  2.   

    重新写了一遍,还是不行,快要疯掉了@_@[StructLayout(LayoutKind.Sequential)]
            public class iLBC_ULP_Inst_t
            {
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = 6 * (ULP_CLASSES + 2))]
                public int[,] lsf_bits = new int[6, ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = ULP_CLASSES + 2)]
                public int[] start_bits = new int[ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = ULP_CLASSES + 2)]
                public int[] startfirst_bits = new int[ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = ULP_CLASSES + 2)]
                public int[] scale_bits = new int[ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = ULP_CLASSES + 2)]
                public int[] state_bits = new int[ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = CB_NSTAGES * (ULP_CLASSES + 2))]
                public int[,] extra_cb_index = new int[CB_NSTAGES, ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = CB_NSTAGES * (ULP_CLASSES + 2))]
                public int[,] extra_cb_gain = new int[CB_NSTAGES, ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = (NSUB_MAX * CB_NSTAGES * (ULP_CLASSES + 2)))]
                public int[, ,] cb_index = new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.SysInt, SizeConst = (NSUB_MAX * CB_NSTAGES * (ULP_CLASSES + 2)))]
                public int[, ,] cb_gain = new int[NSUB_MAX, CB_NSTAGES, ULP_CLASSES + 2];        };
      

  3.   

    [StructLayout(LayoutKind.Sequential)]
            public class iLBC_Enc_Inst_t
            {
                /* flag for frame size mode */
                [MarshalAs(UnmanagedType.I4)]
                public int mode;            /* basic parameters for different frame sizes */
                [MarshalAs(UnmanagedType.I4)]
                public int blockl;            [MarshalAs(UnmanagedType.I4)]
                public int nsub;            [MarshalAs(UnmanagedType.I4)]
                public int nasub;            [MarshalAs(UnmanagedType.I4)]
                public int no_of_bytes, no_of_words;            [MarshalAs(UnmanagedType.I4)]
                public int lpc_n;            [MarshalAs(UnmanagedType.I4)]
                public int state_short_len;            //[MarshalAs(UnmanagedType.LPStruct)]
                //public iLBC_ULP_Inst_t ULP_inst;
                // 替换为下面的形式:
                [MarshalAs(UnmanagedType.LPStruct)]
                public IntPtr ULP_inst = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(iLBC_ULP_Inst_t)));            /* analysis filter state */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER)]
                public float[] anaMem = new float[LPC_FILTERORDER];            /* old lsf parameters for interpolation */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER)]
                public float[] lsfold = new float[LPC_FILTERORDER];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER)]
                public float[] lsfdeqold = new float[LPC_FILTERORDER];            /* signal buffer for LP analysis */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_LOOKBACK + BLOCKL_MAX)]
                public float[] lpc_buffer = new float[LPC_LOOKBACK + BLOCKL_MAX];            /* state of input HP filter */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 4)]
                public float[] hpimem = new float[4];        };
      

  4.   

    [StructLayout(LayoutKind.Sequential)]
            public class iLBC_Dec_Inst_t
            {
                /* flag for frame size mode */
                [MarshalAs(UnmanagedType.SysInt)]
                public int mode;            /* basic parameters for different frame sizes */
                [MarshalAs(UnmanagedType.SysInt)]
                public int blockl;            [MarshalAs(UnmanagedType.SysInt)]
                public int nsub;            [MarshalAs(UnmanagedType.SysInt)]
                public int nasub;            [MarshalAs(UnmanagedType.SysInt)]
                public int no_of_bytes;            [MarshalAs(UnmanagedType.SysInt)]
                public int no_of_words;            [MarshalAs(UnmanagedType.SysInt)]
                public int lpc_n;            [MarshalAs(UnmanagedType.SysInt)]
                public int state_short_len;            //[MarshalAs(UnmanagedType.LPStruct)]
                //public iLBC_ULP_Inst_t ULP_inst;
                [MarshalAs(UnmanagedType.LPStruct)]
                public IntPtr ULP_inst = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(iLBC_ULP_Inst_t)));            /* synthesis filter state */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER)]
                public float[] syntMem = new float[LPC_FILTERORDER];            /* old LSF for interpolation */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER)]
                public float[] lsfdeqold = new float[LPC_FILTERORDER];            /* pitch lag estimated in enhancer and used in PLC */
                [MarshalAs(UnmanagedType.SysInt)]
                public int last_lag;            /* PLC state information */
                [MarshalAs(UnmanagedType.SysInt)]
                public int prevLag;            [MarshalAs(UnmanagedType.SysInt)]
                public int consPLICount;            [MarshalAs(UnmanagedType.SysInt)]
                public int prevPLI;            [MarshalAs(UnmanagedType.SysInt)]
                public int prev_enh_pl;            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = LPC_FILTERORDER + 1)]
                public float[] prevLpc = new float[LPC_FILTERORDER + 1];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = NSUB_MAX * SUBL)]
                public float[] prevResidual = new float[NSUB_MAX * SUBL];            [MarshalAs(UnmanagedType.R4)]
                public float per;            [MarshalAs(UnmanagedType.U4)]
                public uint seed;
                /* previous synthesis filter parameters */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = (LPC_FILTERORDER + 1) * NSUB_MAX)]
                public float[] old_syntdenum = new float[(LPC_FILTERORDER + 1) * NSUB_MAX];            /* state of output HP filter */
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 4)]
                float[] hpomem = new float[4];            /* enhancer state information */
                [MarshalAs(UnmanagedType.SysInt)]
                public int use_enhancer;            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = ENH_BUFL)]
                public float[] enh_buf = new float[ENH_BUFL];            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = ENH_NBLOCKS_TOT)]
                public float[] enh_period = new float[ENH_NBLOCKS_TOT];
            };
      

  5.   

    二维数组没传过,你可以看看float的长度,跟C++的一样吗?
    测试下结构体的字节数跟C++的长度比较下
      

  6.   

    唉,始终没有搞定,我最后把这些复杂参数封装在dll里边了,外部就不传了