need to import weird C struct
-
I am trying to import some functions from an open source library(DLL). //Here is the function definition in C/C++ PJ* pj_init(int argc, char **argv); //Here is the PJ struct in a .h file typedef struct PJconsts { XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); const char *descr; paralist *params; /* parameter list */ int over; /* over-range flag */ int geoc; /* geocentric latitude flag */ int is_latlong; /* proj=latlong ... not really a projection at all */ int is_geocent; /* proj=geocent ... not really a projection at all */ double a, /* major axis or radius if es==0 */ e, /* eccentricity */ es, /* e ^ 2 */ ra, /* 1/A */ one_es, /* 1 - e^2 */ rone_es, /* 1/one_es */ lam0, phi0, /* central longitude, latitude */ x0, y0, /* easting and northing */ k0, /* general scaling factor */ to_meter, fr_meter; /* cartesian scaling */ int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ double datum_params[7]; double from_greenwich; /* prime meridian offset (in radians) */ #ifdef PROJ_PARMS__ PROJ_PARMS__ #endif /* end of optional extensions */ } PJ; I understand that I need to use DLLImport to import the function and [ StructLayout( LayoutKind.Sequential )] to create a clss representing the struct, but I'm clueless on the first 4 lines in the struct above: XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); XY and LP are simple structs typedef struct { double x, y; } XY; typedef struct { double lam, phi; } LP; Any ideas? Thanks, sam
-
I am trying to import some functions from an open source library(DLL). //Here is the function definition in C/C++ PJ* pj_init(int argc, char **argv); //Here is the PJ struct in a .h file typedef struct PJconsts { XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); const char *descr; paralist *params; /* parameter list */ int over; /* over-range flag */ int geoc; /* geocentric latitude flag */ int is_latlong; /* proj=latlong ... not really a projection at all */ int is_geocent; /* proj=geocent ... not really a projection at all */ double a, /* major axis or radius if es==0 */ e, /* eccentricity */ es, /* e ^ 2 */ ra, /* 1/A */ one_es, /* 1 - e^2 */ rone_es, /* 1/one_es */ lam0, phi0, /* central longitude, latitude */ x0, y0, /* easting and northing */ k0, /* general scaling factor */ to_meter, fr_meter; /* cartesian scaling */ int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ double datum_params[7]; double from_greenwich; /* prime meridian offset (in radians) */ #ifdef PROJ_PARMS__ PROJ_PARMS__ #endif /* end of optional extensions */ } PJ; I understand that I need to use DLLImport to import the function and [ StructLayout( LayoutKind.Sequential )] to create a clss representing the struct, but I'm clueless on the first 4 lines in the struct above: XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); XY and LP are simple structs typedef struct { double x, y; } XY; typedef struct { double lam, phi; } LP; Any ideas? Thanks, sam
The XY and LP structs are easy:
[StructLayout(LayoutKind.Sequential)]
public struct XY
{
public double x;
public double y;
}
[StructLayout(LayoutKind.Sequential)]
public struct LP
{
public double lam;
public double phi;
}If you look at the
PJconsts
struct, though, it's actually being used as a class (possible in C++). You should instead define this as a class, keeping in mind that anything declared as aclass
is a reference Type already, so you don't need a pointer to it. If you need to pass a reference to a value type (likestruct
s, for example), use either theout
orref
keyword, depending on whether or not the param is defined as[out]
or[in,out]
respectively.-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
-
The XY and LP structs are easy:
[StructLayout(LayoutKind.Sequential)]
public struct XY
{
public double x;
public double y;
}
[StructLayout(LayoutKind.Sequential)]
public struct LP
{
public double lam;
public double phi;
}If you look at the
PJconsts
struct, though, it's actually being used as a class (possible in C++). You should instead define this as a class, keeping in mind that anything declared as aclass
is a reference Type already, so you don't need a pointer to it. If you need to pass a reference to a value type (likestruct
s, for example), use either theout
orref
keyword, depending on whether or not the param is defined as[out]
or[in,out]
respectively.-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
Yeah XY and LP are easy, my problem is the PJconsts struct..... which is really the PJ struct, I think the PJconsts is some type of C label, while PJ is the actual name. This thread http://forums.devshed.com/archive/42/2003/9/1/80923 talks a bit about it... and what is the deal with the first 4 lines of the struct.....
-
Yeah XY and LP are easy, my problem is the PJconsts struct..... which is really the PJ struct, I think the PJconsts is some type of C label, while PJ is the actual name. This thread http://forums.devshed.com/archive/42/2003/9/1/80923 talks a bit about it... and what is the deal with the first 4 lines of the struct.....
They're method declarations, which is why I was saying that this could be better suited for a class. This was a way in C to declare class-like entities.
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
-
I am trying to import some functions from an open source library(DLL). //Here is the function definition in C/C++ PJ* pj_init(int argc, char **argv); //Here is the PJ struct in a .h file typedef struct PJconsts { XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); const char *descr; paralist *params; /* parameter list */ int over; /* over-range flag */ int geoc; /* geocentric latitude flag */ int is_latlong; /* proj=latlong ... not really a projection at all */ int is_geocent; /* proj=geocent ... not really a projection at all */ double a, /* major axis or radius if es==0 */ e, /* eccentricity */ es, /* e ^ 2 */ ra, /* 1/A */ one_es, /* 1 - e^2 */ rone_es, /* 1/one_es */ lam0, phi0, /* central longitude, latitude */ x0, y0, /* easting and northing */ k0, /* general scaling factor */ to_meter, fr_meter; /* cartesian scaling */ int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ double datum_params[7]; double from_greenwich; /* prime meridian offset (in radians) */ #ifdef PROJ_PARMS__ PROJ_PARMS__ #endif /* end of optional extensions */ } PJ; I understand that I need to use DLLImport to import the function and [ StructLayout( LayoutKind.Sequential )] to create a clss representing the struct, but I'm clueless on the first 4 lines in the struct above: XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); XY and LP are simple structs typedef struct { double x, y; } XY; typedef struct { double lam, phi; } LP; Any ideas? Thanks, sam
XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); Obviously, we dealing with function pointers here, aka CALLBACK. You can safely use
static
delegate instances for this. I'm not sure about returning those structs, marshalling could give you either a pointer or a value, you will just have to try. leppie::AllocCPArticle("Zee blog");
Seen on my Campus BBS: Linux is free...coz no-one wants to pay for it. -
XY (*fwd)(LP, struct PJconsts *); LP (*inv)(XY, struct PJconsts *); void (*spc)(LP, struct PJconsts *, struct FACTORS *); void (*pfree)(struct PJconsts *); Obviously, we dealing with function pointers here, aka CALLBACK. You can safely use
static
delegate instances for this. I'm not sure about returning those structs, marshalling could give you either a pointer or a value, you will just have to try. leppie::AllocCPArticle("Zee blog");
Seen on my Campus BBS: Linux is free...coz no-one wants to pay for it.I'm still having problems with the marshalling I get an exception "Can not marshal field param of type ProjWrapper.PJ: The type definition of this field has no layout information." I have tagged it with Layout.Sequential
//XY (*fwd)(LP, struct PJconsts *); original public delegate XY fwd(LP lp, PJ pj); ///etc [StructLayout(LayoutKind.Sequential)] public class PJ { fwd fwdcallback; //etc }
Could the problem be in the return Marshal of the PJ class, or am I messing up the callback definitions still Thank you very much for your help.... -Sam -
I'm still having problems with the marshalling I get an exception "Can not marshal field param of type ProjWrapper.PJ: The type definition of this field has no layout information." I have tagged it with Layout.Sequential
//XY (*fwd)(LP, struct PJconsts *); original public delegate XY fwd(LP lp, PJ pj); ///etc [StructLayout(LayoutKind.Sequential)] public class PJ { fwd fwdcallback; //etc }
Could the problem be in the return Marshal of the PJ class, or am I messing up the callback definitions still Thank you very much for your help.... -Sam -
sammyh wrote: fwd fwdcallback; //etc Somewhere after the //etc is the error leppie::AllocCPArticle("Zee blog");
Seen on my Campus BBS: Linux is free...coz no-one wants to pay for it.alright... progress, seems to be working The last 2 hurdles First I was doing this
[StructLayout(LayoutKind.Sequential)] public class paralist { paralist next; char used; char param; }
when it likes this better[StructLayout(LayoutKind.Sequential)] public unsafe class paralist { paralist *next; char used; char param; }
Second, I had to replacefwd fwdcallback;
withint fwdcallback;
Thanks again.