none
P/invoke setting structure - error (" Method's type signature is not PInvoke compatible.") RRS feed

  • Question

  • Hellow to all CLR gurus. :)

     

    Short question:

    How to set next struct for P/Invoke:

    Native structure in C:

    typedef struct {
    ...
    ...
    ...
    double criterion[C_MAX];     /* array of model selection statistics */
    ...
    ...
    } MODEL;
    
    
    
    

    Hint: This is not working!

    [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
    public struct MODEL
    {
    ...
    ...
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
     public double[] criterion;
    ...
    ...
    ...
    }
    

     

     

    Ok, long question:

    I am working on connecting Gretl API (some program for statistic) with C#. Now I hit on a wall. I'm trying to set correct structure for structure Model. In native - C language looks like this:

    typedef struct {
        int ID;                      /* ID number for model */
        int refcount;                /* for saving/deleting */
        int ci;                      /* "command index" -- estimation method */
        gretlopt opt;                /* record of options */
        int t1, t2, nobs;            /* starting observation, ending
                                        observation, and number of obs */
        char *submask;               /* keep track of sub-sample in force
                                        when model was estimated */
        char *missmask;              /* missing observations mask */
        SAMPLE smpl;                 /* numeric start and end of current sample
                                        when model was estimated */
        int full_n;                  /* full length of dataset on estimation */
        int ncoeff, dfn, dfd;        /* number of coefficents; degrees of
                                        freedom in numerator and denominator */
        int *list;                   /* list of variables by ID number */
        int ifc;                     /* = 1 if the equation includes a constant,
    				    else = 0 */
        int nwt;                     /* ID number of the weight variable (WLS) */
        int aux;                     /* code representing the sort of
    				    auxiliary regression this is (or not) */
        double *coeff;               /* array of coefficient estimates */
        double *sderr;               /* array of estimated std. errors */
        double *uhat;                /* regression residuals */
        double *yhat;                /* fitted values from regression */
        double *xpx;                 /* X'X matrix, in packed form */
        double *vcv;                 /* VCV matrix for coefficient estimates */
        double ess, tss;             /* Error and Total Sums of Squares */
        double sigma;                /* Standard error of regression */
        double rsq, adjrsq;          /* Unadjusted and adjusted R^2 */     
        double fstt;                 /* overall F-statistic */
        double chisq;                /* overall chi-square statistic */
        double lnL;                  /* log-likelihood */
        double ybar, sdy;            /* mean and std. dev. of dependent var. */
        double criterion[C_MAX];     /* array of model selection statistics */
        double dw, rho;              /* Durbin-Watson stat. and estimated 1st
    				    order autocorrelation coefficient */
        ARINFO *arinfo;              /* pointer to struct to hold special info for 
    				    autoregressive model */ 
        int errcode;                 /* Error code in case of failure */
        char *name;                  /* for use in GUI */
        char *depvar;                /* name of dependent var in special cases */
        int nparams;                 /* number of named model parameters */
        char **params;               /* for named model parameters */
        int ntests;                  /* number of attached test results */
        ModelTest *tests;            /* attached hypothesis test results */
        DATASET *dataset;            /* for handling models estimated on a
    				    sub-sampled portion of the dataset */
        int n_data_items;            /* number of extra data items */
        model_data_item **data_items; /* pointer to additional data */
    } MODEL;
    
    

    So far I have come to this:

            [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
            public struct MODEL
            {
                public int ID;           // ID number for model
                public int refcount;     // for saving/deleting
                public int ci;           // "command index" -- estimation method
                public int opt;     // record of options gretlopt
                public int t1;           // starting observation
                public int t2;           // ending observation
                public int nobs;         // number of observations
                //[MarshalAsAttribute(UnmanagedType.LPStr)]
                //public string submask;   // keep track of sub-sample in force when model was estimated   -- char *submask
                public IntPtr submask;
                //[MarshalAsAttribute(UnmanagedType.LPStr)]
                //public string missmask;      // missing observations mask    -- char * missmark
                public IntPtr missmask;
                public SAMPLE smpl;          // numeric start and end of current sample when model was estimated
                public int full_n;           // full length of datase on esimation          
                public int ncoeff;           // number of coefficents
                public int dfn;              // degress of freedom in numerator
                public int dfd;              // degress of freedom in denominator
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_INT)]
                //public int[] list;           // list of variables by ID number
                public IntPtr list;
                public int ifc;             // =1 if the equation includes a constant, else = 0 
                public int nwt;             // ID number of the weight variable (WLS)
                public int aux;             // code representing the sort of auxiliary regression this is (or not)
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] coeff;          // array of coefficient estimates
                public IntPtr coeff;
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] sderr;          // array of estimated std. errors
                public IntPtr sderr;
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] uhat;           // regression residuals
                public IntPtr uhat;
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] yhat;           // fitted values for regression
                public IntPtr yhat;
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] xpx;            // X'X matrix, in packed form
                public IntPtr xpx;
                //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)]
                //public double[] vcv;            // VCV matrix for coefficient estimates
                public IntPtr vcv;
                public double ess;              // Error 
                public double tss;              // Total Sums of Squares
                public double sigma;            // Standart error of regression
                public double rsq;              // Unadjusted R^2
                public double adjrsq;           // Adjusted R^2
                public double fstt;             // overall F-statistic
                public double chisq;            // overall chi-square statistic
                public double lnL;              // log-likelihood
                public double ybar;             // mean dev. of depandent var.
                public double sdy;              // std. dev. of depandent var.
    
                [MarshalAs(UnmanagedType.ByValArray)]
                public double[] criterion;
                //IntPtr criterion;
                public double dw;               // Durbin-Watson stat. 
                public double rho;              // estimated 1st order autocorrelation coefficient
                public IntPtr arinfo;           // ARINFO *arinfo -- pointer to struct to hold special info for autoregressive model
                public int errcode;             // Error code in case of failure
                public IntPtr name;            // for use in GUI   --char*
                //[MarshalAsAttribute(UnmanagedType.LPStr)]
                //public string depvar;          // name of depandent var in special cases -- char*
                public IntPtr depvar;
                public int nparams;             // number of named model parameter 
                ////[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
                ////public string[] params1;         // char** -- for named model parameters
                public IntPtr @params;
                public int ntests;              // number of attached test results
                public IntPtr tests;            // ModelTest *tests -- attached hypothesis test results
                public IntPtr dataset;          // for handeling models estimated on a sub-sampled portion of the dataset
                public int n_data_items;        // number of extra data items
                public IntPtr data_items;       // model_data_item **data_items -- pointer to additional data
            }
    


    I have tried some of automatic generaton tool like  P/invoke wizard and CLRInsideOut. But nothing seems to help( none of generated code seems to work)

    I'm calling Gretl's function lad

    Native:

    MODEL lad  (const int *list, DATASET *dset);

    P/invoke:

            [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
            public static extern Structures.MODEL lad(IntPtr list, ref Structures.DATASET dataset);

    and get MarshalDirectiveException ( Method's type signature is not PInvoke compatible.)

    But if I change parameter double[] criterion into IntPtr I get

    PInvokeStackImbalance (A call to PInvoke function 'GretlCore!GretlCore.NativeGretl.Methods::lad' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.)

     

    Any hint or solution would be GREATLY appreciated.

    Have a nice day!

    Saymon

     

     

    Sunday, November 6, 2011 2:55 PM

Answers

  • I suggest you use IntPtr type instead of the double array, and When you pass the structure as a parameter of "lad" method, also use IntPtr instead of structure.

    Then use AllocHGlobal to allocate memory from the unmanaged memory of the process by using the specified number of bytes. You know the size of the double array and structure, so you can allocate specified size of unmanaged memory.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Saymon Rupar Saturday, November 12, 2011 11:47 PM
    Friday, November 11, 2011 8:10 AM
  • [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct SAMPLE {
        
        /// int
        public int t1;
        
        /// int
        public int t2;
    }
    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct MODEL {
        
        /// int
        public int ID;
        
        /// int
        public int refcount;
        
        /// int
        public int ci;
        
        /// gretlopt->???
        public gretlopt opt;
        
        /// int
        public int t1;
        
        /// int
        public int t2;
        
        /// int
        public int nobs;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string submask;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string missmask;
        
        /// SAMPLE->SAMPLE
        public SAMPLE smpl;
        
        /// int
        public int full_n;
        
        /// int
        public int ncoeff;
        
        /// int
        public int dfn;
        
        /// int
        public int dfd;
        
        /// int*
        public System.IntPtr list;
        
        /// int
        public int ifc;
        
        /// int
        public int nwt;
        
        /// int
        public int aux;
        
        /// double*
        public System.IntPtr coeff;
        
        /// double*
        public System.IntPtr sderr;
        
        /// double*
        public System.IntPtr uhat;
        
        /// double*
        public System.IntPtr yhat;
        
        /// double*
        public System.IntPtr xpx;
        
        /// double*
        public System.IntPtr vcv;
        
        /// double
        public double ess;
        
        /// double
        public double tss;
        
        /// double
        public double sigma;
        
        /// double
        public double rsq;
        
        /// double
        public double adjrsq;
        
        /// double
        public double fstt;
        
        /// double
        public double chisq;
        
        /// double
        public double lnL;
        
        /// double
        public double ybar;
        
        /// double
        public double sdy;
        
        /// double[]
        public double[] criterion;
        
        /// double
        public double dw;
        
        /// double
        public double rho;
        
        /// ARINFO*
        public System.IntPtr arinfo;
        
        /// int
        public int errcode;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string name;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string depvar;
        
        /// int
        public int nparams;
        
        /// char**
        public System.IntPtr @params;
        
        /// int
        public int ntests;
        
        /// ModelTest*
        public System.IntPtr tests;
        
        /// DATASET*
        public System.IntPtr dataset;
        
        /// int
        public int n_data_items;
        
        /// model_data_item**
        public System.IntPtr data_items;
    }
    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem. 
    Visual C++ MVP


    Sunday, November 6, 2011 11:06 PM
  • After may tests and writing samples, I think that problems lie in already generated API. Sorry for all the fus and THANK YOU for all the help. 

     

    Too further elaberate:

     

     

    /// <summary>
    /// Estimate the model given in list using the method of Least Absolute Deviation (LAD). 
    /// </summary>
    /// <param name="list">	dependent variable plus list of regressors.</param>
    /// <param name="dataset">dataset struct.</param>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern Structures.MODEL lad(IntPtr list, ref Structures.DATASET dataset);

    should be called like:

    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern void lad(IntPtr pointerToReturnModel, IntPtr list, ref Structures.DATASET dataset);

    It helped in all my test samples, but not in my project. So I think it is the problem with generated API.

    Thank you all for pointing me to right direction, and bearing with me. 

     

    • Marked as answer by Saymon Rupar Saturday, November 12, 2011 11:47 PM
    • Edited by Saymon Rupar Sunday, November 13, 2011 11:15 AM
    Saturday, November 12, 2011 11:47 PM

All replies

  • Array size is required for the default marshaller to copy data to the managed heap. If you do not know the size at compilation or the address you want to pass is on the native heap, you can pass the array's address in an intptr then use Marshal to copy the data.

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Sunday, November 6, 2011 3:49 PM
  • Use GChandle to alloc a byte() and pass it to the called method. Use a BinaryReader to retrieve the data from a memory stream constructed from the byte() or use the byte() directly.  Put everything in its own class.
    • Edited by JohnWein Sunday, November 6, 2011 6:22 PM
    Sunday, November 6, 2011 6:20 PM
  • Helow Sheng Jiang

    Thank you for your replay. I know the size of array and have made correction thah you mention. Now it looks like this.

    Model
    {
    ....       
               [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
                public double[]  criterion;
    ....
    }
    

    Hope that you ment. But still it does not work. I have also try as IntPtr but would not work. Except if you can pass array's address some other way.

    I think my problem is because my struct Model is not a Blittable.

    Sunday, November 6, 2011 6:49 PM
  • Hey JohnWein

    Thanks for replay.

    I think you make a good point. But I need some time to figure it out, how to do that. :) Not so skilled in CRL yet. I was hoping for some "elegent" solution, but nevertheless. I will let you know if it works.

    Sunday, November 6, 2011 7:12 PM
  • sorry, I overlooked your structure, the array size only apply to types that are already arrays (e.g. doube var[4])

    If you have address to pass, pass them as IntPtr, and use Marshal.Copy/Marshal.PtrToStructure to copy data pointed by the address to the managed heap when needed.



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Sunday, November 6, 2011 7:19 PM
  • I think you make a good point. But I need some time to figure it out, how to do that. :) Not so skilled in CRL yet. I was hoping for some "elegent" solution, but nevertheless. I will let you know if it works.


    It's tedious the first time you do it, but it saves a lot of hair the next time you have a P/Invoke problem.
    Sunday, November 6, 2011 7:21 PM
  • I think I didn't specify my problem quite enough.

    I am doing:

    /// <summary>
    /// Allocates memory for a gretl MODEL struct and initializes the struct, using gretl_model_init(). 
    /// </summary>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "gretl_model_new", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr gretl_model_new();
    
    /// <summary>
    /// Estimate the model given in list using the method of Least Absolute Deviation (LAD). 
    /// </summary>
    /// <param name="list">	dependent variable plus list of regressors.</param>
    /// <param name="dataset">dataset struct.</param>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern Structures.MODEL lad(IntPtr list, ref Structures.DATASET dataset);
    
    
    main()
    {
    IntPtr pointerModel = GretlCore.NativeGretl.Methods.gretl_model_new();
    
    GretlCore.NativeGretl.Structures.MODEL model = (GretlCore.NativeGretl.Structures.MODEL)Marshal.PtrToStructure(pointerModel, typeof(GretlCore.NativeGretl.Structures.MODEL));
    
    model = GretlCore.NativeGretl.Methods.lad(pointerList, ref pddata);
    }
    

    On which method "gretl_model_new()", works almost fine (I think- don't get exception), but when I want to set "model" it comes to problem.
    I read on MSDN it comes to the problem because the struct is not Blittable - because of the array in struct.

    So I think that problem is with unmanaged heap, or because it does not see managed heap. In managed heap works.

    Thanks for bearing with me.

    Sunday, November 6, 2011 8:42 PM
  • Yes gretl_model_new has nothing to marshal and should not error out - that is, unless you are returning an address on the stack. But from the method name, it looks like the returned address is on the heap.
    It is unclear how you marshalled the SAMPLE structure, everything else looks fine as you are using IntPtr. 


    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Sunday, November 6, 2011 9:00 PM
  • Here is SAMPLE

    Marshal SAMPLE:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct SAMPLE
    {
          public int t1;
          public int t2;
    }
    


    from:

    typedef struct {
        int t1;
        int t2;
    } SAMPLE;
    


    Sunday, November 6, 2011 9:07 PM
  • [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct SAMPLE {
        
        /// int
        public int t1;
        
        /// int
        public int t2;
    }
    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct MODEL {
        
        /// int
        public int ID;
        
        /// int
        public int refcount;
        
        /// int
        public int ci;
        
        /// gretlopt->???
        public gretlopt opt;
        
        /// int
        public int t1;
        
        /// int
        public int t2;
        
        /// int
        public int nobs;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string submask;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string missmask;
        
        /// SAMPLE->SAMPLE
        public SAMPLE smpl;
        
        /// int
        public int full_n;
        
        /// int
        public int ncoeff;
        
        /// int
        public int dfn;
        
        /// int
        public int dfd;
        
        /// int*
        public System.IntPtr list;
        
        /// int
        public int ifc;
        
        /// int
        public int nwt;
        
        /// int
        public int aux;
        
        /// double*
        public System.IntPtr coeff;
        
        /// double*
        public System.IntPtr sderr;
        
        /// double*
        public System.IntPtr uhat;
        
        /// double*
        public System.IntPtr yhat;
        
        /// double*
        public System.IntPtr xpx;
        
        /// double*
        public System.IntPtr vcv;
        
        /// double
        public double ess;
        
        /// double
        public double tss;
        
        /// double
        public double sigma;
        
        /// double
        public double rsq;
        
        /// double
        public double adjrsq;
        
        /// double
        public double fstt;
        
        /// double
        public double chisq;
        
        /// double
        public double lnL;
        
        /// double
        public double ybar;
        
        /// double
        public double sdy;
        
        /// double[]
        public double[] criterion;
        
        /// double
        public double dw;
        
        /// double
        public double rho;
        
        /// ARINFO*
        public System.IntPtr arinfo;
        
        /// int
        public int errcode;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string name;
        
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string depvar;
        
        /// int
        public int nparams;
        
        /// char**
        public System.IntPtr @params;
        
        /// int
        public int ntests;
        
        /// ModelTest*
        public System.IntPtr tests;
        
        /// DATASET*
        public System.IntPtr dataset;
        
        /// int
        public int n_data_items;
        
        /// model_data_item**
        public System.IntPtr data_items;
    }
    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem. 
    Visual C++ MVP


    Sunday, November 6, 2011 11:06 PM
  • Do you get a valid byte() back when you call lad?  Can you get the individual entries?
    Sunday, November 6, 2011 11:17 PM
  • Sorry Sheng Jiang,  but with your structure still doesn't work. It fail's when I call Marshal.PtrToStructure - Attempt to read or write proteced memory...

    Thank you for sticking around. :)

    Monday, November 7, 2011 11:38 AM
  • Sorry John, still working on it, I will let you know the minute I figure it out.
    Monday, November 7, 2011 11:38 AM
  • Use GChandle to alloc a byte() and pass it to the called method. Use a BinaryReader to retrieve the data from a memory stream constructed from the byte() or use the byte() directly.  Put everything in its own class.

    Hey JohnWein

     

    I'm banging my head on this, can you direct me to some sample or something. How do you alloc a byte(). You mean some byte array, cus byte type is to small for mine struct :P

    Monday, November 7, 2011 12:48 PM
  • Pasting my code sample :

    Sample:

     

    You also have to install Gretl from:

    Gretl

     

    In code you have to correct the path to Gretl installation dir in Native.Constants. Hope this will help reveal my real problem


    • Edited by Saymon Rupar Monday, November 7, 2011 1:20 PM Links
    Monday, November 7, 2011 1:18 PM
  • Sorry.  I'm a vb'er.  byte[] in C#.
    Monday, November 7, 2011 3:18 PM
  • You commented out [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] on the MODEL structure for some reason, the sample works fine when I uncommented the line.

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Monday, November 7, 2011 5:43 PM
  • Hm... Funny. I get stackunbalanced on call

    model = Methods.lad(list, ref pddata);
    

    I will look into it...

    Monday, November 7, 2011 10:45 PM
  • Would you mind letting us know the result of the suggestions?

     

    If you have got answers, please remember to mark answer and close this thread.

    If not, any more concerns, please feel free to let us know.

     

    Have a nice day!


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, November 10, 2011 6:33 AM
  • Hey sorry for my late replay. Problem persists. Right now I am trying to write c++ wrapper.
    Thursday, November 10, 2011 3:23 PM
  • Still waiting if someone know solution to problem....
    Thursday, November 10, 2011 10:42 PM
  • I suggest you use IntPtr type instead of the double array, and When you pass the structure as a parameter of "lad" method, also use IntPtr instead of structure.

    Then use AllocHGlobal to allocate memory from the unmanaged memory of the process by using the specified number of bytes. You know the size of the double array and structure, so you can allocate specified size of unmanaged memory.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Saymon Rupar Saturday, November 12, 2011 11:47 PM
    Friday, November 11, 2011 8:10 AM
  • Hey Paul Zhou

    First thank you for replay. I have already tried that approch and didn't work. Beside I don't know if you can call IntPtr on fixed array. I have also tried calling everything in unsafe context. The main problem is next:

    I can make call(if I may repost):

    /// <summary>
    /// Allocates memory for a gretl MODEL struct and initializes the struct, using gretl_model_init(). 
    /// </summary>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "gretl_model_new", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr gretl_model_new();
    
    /// <summary>
    /// Estimate the model given in list using the method of Least Absolute Deviation (LAD). 
    /// </summary>
    /// <param name="list">	dependent variable plus list of regressors.</param>
    /// <param name="dataset">dataset struct.</param>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern Structures.MODEL lad(IntPtr list, ref Structures.DATASET dataset);
    
    
    main()
    {
    IntPtr pointerModel = GretlCore.NativeGretl.Methods.gretl_model_new();
    
    GretlCore.NativeGretl.Structures.MODEL model = (GretlCore.NativeGretl.Structures.MODEL)Marshal.PtrToStructure(pointerModel, typeof(GretlCore.NativeGretl.Structures.MODEL));
    
    model = GretlCore.NativeGretl.Methods.lad(pointerList, ref pddata);
    }

     

    The problematic call is last one (StackUnbalanced). I can't also change API...

    I will try to make some test samples ( make my API and tried call structure), and I will post the resolts in a day or two.

     

    Have a nice day!

     

    Friday, November 11, 2011 11:53 AM
  • After may tests and writing samples, I think that problems lie in already generated API. Sorry for all the fus and THANK YOU for all the help. 

     

    Too further elaberate:

     

     

    /// <summary>
    /// Estimate the model given in list using the method of Least Absolute Deviation (LAD). 
    /// </summary>
    /// <param name="list">	dependent variable plus list of regressors.</param>
    /// <param name="dataset">dataset struct.</param>
    /// <returns></returns>
    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern Structures.MODEL lad(IntPtr list, ref Structures.DATASET dataset);

    should be called like:

    [DllImport(Constants.gretlLibraryPath, EntryPoint = "lad", CallingConvention = CallingConvention.Cdecl)]
    public static extern void lad(IntPtr pointerToReturnModel, IntPtr list, ref Structures.DATASET dataset);

    It helped in all my test samples, but not in my project. So I think it is the problem with generated API.

    Thank you all for pointing me to right direction, and bearing with me. 

     

    • Marked as answer by Saymon Rupar Saturday, November 12, 2011 11:47 PM
    • Edited by Saymon Rupar Sunday, November 13, 2011 11:15 AM
    Saturday, November 12, 2011 11:47 PM