|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
To overload, or not to overload?In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is ///// GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList ( HDC aDC, // Device context to draw to GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all uint32 aLayerCount, // Number of layers in list (0 for all) GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all sint32 aLeftPixel, // Left pixel coordinate to draw to sint32 aTopPixel, // Top pixel coordinate to draw to sint32 aPixelWidth, // Width in pixels to draw sint32 aPixelHeight // Height in pixels to draw ); ///// which I originally translated to ///// Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ ( _ ByVal aDC As IntPtr, _ ByRef aLayerList As GM_LayerHandle_t32, _ ByVal aLayerCount As Int32, _ ByVal aDrawFlags As GM_DrawFlags_t32, _ ByRef aWorldBounds As GM_Rectangle_t, _ ByVal aLeftPixel As Int32, _ ByVal aTopPixel As Int32, _ ByVal aPixelWidth As Int32, _ ByVal aPixelHeight As Int32 _ ) As GM_Error_t32 ///// but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the function in order to represent NULL) when the 5th argument was expecting the GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to draw all layers. So, I overloaded the function as such ///// Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ ( _ ByVal aDC As IntPtr, _ ByRef aLayerList As GM_LayerHandle_t32, _ ByVal aLayerCount As Int32, _ ByVal aDrawFlags As GM_DrawFlags_t32, _ ByVal aWorldBounds As IntPtr, _ ByVal aLeftPixel As Int32, _ ByVal aTopPixel As Int32, _ ByVal aPixelWidth As Int32, _ ByVal aPixelHeight As Int32 _ ) As GM_Error_t32 ///// Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it accepts a NULL argument for the 5th parameter in order to get the function to draw all layers. I suppose that's all well and good and everything seems to work fine, but the developer of the DLL - who admittedly is not a VB expert - thinks that there should be a better way to it in VB so that I don't have to duplicate the function prototypes (I would imagine some function prototypes would require more than just 1 overload. For example, I think I would need to overload the above function declare a couple of more times to account for the second argument - which can also receive NULL or a structure - and then any combination of the two arguments that can receive a NULL or structure.) Is there a more efficient way to go about this on my end? Thanks, Lance Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. No
need to pass it by ref since it's an in parameter. Then just pass Nothing to it. /claes Show quoteHide quote "Lance" <nu***@business.com> wrote in message news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... > That is the question. > > In an unmanaged C++ DLL I'm making calls to, one of the function > prototypes is > > ///// > GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList > ( > HDC aDC, // Device context to draw to > GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all > uint32 aLayerCount, // Number of layers in list (0 for all) > GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is > performed > const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for > all > sint32 aLeftPixel, // Left pixel coordinate to draw to > sint32 aTopPixel, // Top pixel coordinate to draw to > sint32 aPixelWidth, // Width in pixels to draw > sint32 aPixelHeight // Height in pixels to draw > ); > ///// > which I originally translated to > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByRef aWorldBounds As GM_Rectangle_t, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > but I couldn't figure out how get it to receive NULL (I was sending > IntPtr.Zero to the function in order to represent NULL) when the 5th > argument was expecting the GM_Rectangle_t structure. NULL needs to be > sent to the function in order for it to draw all layers. So, I overloaded > the function as such > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aWorldBounds As IntPtr, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it > accepts a NULL argument for the 5th parameter in order to get the function > to draw all layers. I suppose that's all well and good and everything > seems to work fine, but the developer of the DLL - who admittedly is not a > VB expert - thinks that there should be a better way to it in VB so that I > don't have to duplicate the function prototypes (I would imagine some > function prototypes would require more than just 1 overload. For example, > I think I would need to overload the above function declare a couple of > more times to account for the second argument - which can also receive > NULL or a structure - and then any combination of the two arguments that > can receive a NULL or structure.) Is there a more efficient way to go > about this on my end? > > Thanks, > Lance > Changing it to
///// Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ ( _ ByVal aDC As IntPtr, _ ByRef aLayerList As GM_LayerHandle_t32, _ ByVal aLayerCount As Int32, _ ByVal aDrawFlags As GM_DrawFlags_t32, _ ByVal aWorldBounds As GM_Rectangle_t, _ ByVal aLeftPixel As Int32, _ ByVal aTopPixel As Int32, _ ByVal aPixelWidth As Int32, _ ByVal aPixelHeight As Int32 _ ) As GM_Error_t32 ///// then sending "Nothing" (without the quotes, of course) as the 5th argument results in a PInvokeStackImbalance. Lance Show quoteHide quote "Claes Bergefall" <louplou@nospam.nospam> wrote in message news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... > Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. No need to pass it > by ref since it's an in parameter. Then just pass Nothing to it. > > /claes > > > "Lance" <nu***@business.com> wrote in message > news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >> That is the question. >> >> In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is >> >> ///// >> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >> ( >> HDC aDC, // Device context to draw to >> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all >> uint32 aLayerCount, // Number of layers in list (0 for all) >> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed >> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all >> sint32 aLeftPixel, // Left pixel coordinate to draw to >> sint32 aTopPixel, // Top pixel coordinate to draw to >> sint32 aPixelWidth, // Width in pixels to draw >> sint32 aPixelHeight // Height in pixels to draw >> ); >> ///// >> which I originally translated to >> >> ///// >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ >> ByRef aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// >> >> but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the >> function in order to represent NULL) when the 5th argument was expecting the >> GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to >> draw all layers. So, I overloaded the function as such >> >> ///// >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ >> ByVal aWorldBounds As IntPtr, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// >> >> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it accepts a NULL >> argument for the 5th parameter in order to get the function to draw all layers. I >> suppose that's all well and good and everything seems to work fine, but the developer >> of the DLL - who admittedly is not a VB expert - thinks that there should be a better >> way to it in VB so that I don't have to duplicate the function prototypes (I would >> imagine some function prototypes would require more than just 1 overload. For example, >> I think I would need to overload the above function declare a couple of more times to >> account for the second argument - which can also receive NULL or a structure - and then >> any combination of the two arguments that can receive a NULL or structure.) Is there a >> more efficient way to go about this on my end? >> >> Thanks, >> Lance >> > > Hmm, that's a new one. Can you post the definitions of the custom types
(GM_Rectangle_t, GM_LayerHAndle_t32 etc), preferably both the C++ and the ..NET code /claes Show quoteHide quote "Lance" <nu***@business.com> wrote in message news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... > Changing it to > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aWorldBounds As GM_Rectangle_t, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > then sending "Nothing" (without the quotes, of course) as the 5th argument > results in a PInvokeStackImbalance. > > Lance > > > "Claes Bergefall" <louplou@nospam.nospam> wrote in message > news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >> Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. No >> need to pass it by ref since it's an in parameter. Then just pass Nothing >> to it. >> >> /claes >> >> >> "Lance" <nu***@business.com> wrote in message >> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>> That is the question. >>> >>> In an unmanaged C++ DLL I'm making calls to, one of the function >>> prototypes is >>> >>> ///// >>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>> ( >>> HDC aDC, // Device context to draw to >>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for >>> all >>> uint32 aLayerCount, // Number of layers in list (0 for all) >>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is >>> performed >>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for >>> all >>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>> sint32 aTopPixel, // Top pixel coordinate to draw to >>> sint32 aPixelWidth, // Width in pixels to draw >>> sint32 aPixelHeight // Height in pixels to draw >>> ); >>> ///// >>> which I originally translated to >>> >>> ///// >>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>> ( _ >>> ByVal aDC As IntPtr, _ >>> ByRef aLayerList As GM_LayerHandle_t32, _ >>> ByVal aLayerCount As Int32, _ >>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>> ByRef aWorldBounds As GM_Rectangle_t, _ >>> ByVal aLeftPixel As Int32, _ >>> ByVal aTopPixel As Int32, _ >>> ByVal aPixelWidth As Int32, _ >>> ByVal aPixelHeight As Int32 _ >>> ) As GM_Error_t32 >>> ///// >>> >>> but I couldn't figure out how get it to receive NULL (I was sending >>> IntPtr.Zero to the function in order to represent NULL) when the 5th >>> argument was expecting the GM_Rectangle_t structure. NULL needs to be >>> sent to the function in order for it to draw all layers. So, I >>> overloaded the function as such >>> >>> ///// >>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>> ( _ >>> ByVal aDC As IntPtr, _ >>> ByRef aLayerList As GM_LayerHandle_t32, _ >>> ByVal aLayerCount As Int32, _ >>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>> ByVal aWorldBounds As IntPtr, _ >>> ByVal aLeftPixel As Int32, _ >>> ByVal aTopPixel As Int32, _ >>> ByVal aPixelWidth As Int32, _ >>> ByVal aPixelHeight As Int32 _ >>> ) As GM_Error_t32 >>> ///// >>> >>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it >>> accepts a NULL argument for the 5th parameter in order to get the >>> function to draw all layers. I suppose that's all well and good and >>> everything seems to work fine, but the developer of the DLL - who >>> admittedly is not a VB expert - thinks that there should be a better way >>> to it in VB so that I don't have to duplicate the function prototypes (I >>> would imagine some function prototypes would require more than just 1 >>> overload. For example, I think I would need to overload the above >>> function declare a couple of more times to account for the second >>> argument - which can also receive NULL or a structure - and then any >>> combination of the two arguments that can receive a NULL or structure.) >>> Is there a more efficient way to go about this on my end? >>> >>> Thanks, >>> Lance >>> >> >> > > here are the definitions of the custom types in the C++ header file.
///// typedef struct { double mMinX; // Minimum x/easting/longitude coordinate double mMinY; // Minimum y/northing/latitude coordinate double mMaxX; // Maximum x/easting/longitude coordinate double mMaxY; // Maximum y/northing/latitude coordinate } GM_Rectangle_t; typedef void* GM_LayerHandle_t32; ///// and here are my .NET translations ///// Public Structure GM_Rectangle_t Public mMinX As Double ' Minimum x/easting/longitude coordinate Public mMinY As Double ' Minimum y/northing/latitude coordinate Public mMaxX As Double ' Maximum x/easting/longitude coordinate Public mMaxY As Double ' Maximum y/northing/latitude coordinate End Structure ///// for GM_LayerHandle_t32, on the advice of the SDK developer I've defined an Alias as such: ///// Imports GM_LayerHandle_t32 = System.Int32 ///// Lance Show quoteHide quote "Claes Bergefall" <louplou@nospam.nospam> wrote in message news:eEekqagwGHA.976@TK2MSFTNGP05.phx.gbl... > Hmm, that's a new one. Can you post the definitions of the custom types (GM_Rectangle_t, > GM_LayerHAndle_t32 etc), preferably both the C++ and the .NET code > > /claes > > "Lance" <nu***@business.com> wrote in message > news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... >> Changing it to >> >> ///// >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ >> ByVal aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// >> >> then sending "Nothing" (without the quotes, of course) as the 5th argument results in a >> PInvokeStackImbalance. >> >> Lance >> >> >> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >> news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >>> Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. No need to pass >>> it by ref since it's an in parameter. Then just pass Nothing to it. >>> >>> /claes >>> >>> >>> "Lance" <nu***@business.com> wrote in message >>> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>>> That is the question. >>>> >>>> In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is >>>> >>>> ///// >>>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>>> ( >>>> HDC aDC, // Device context to draw to >>>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all >>>> uint32 aLayerCount, // Number of layers in list (0 for all) >>>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed >>>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all >>>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>>> sint32 aTopPixel, // Top pixel coordinate to draw to >>>> sint32 aPixelWidth, // Width in pixels to draw >>>> sint32 aPixelHeight // Height in pixels to draw >>>> ); >>>> ///// >>>> which I originally translated to >>>> >>>> ///// >>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>> ( _ >>>> ByVal aDC As IntPtr, _ >>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>> ByVal aLayerCount As Int32, _ >>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>> ByRef aWorldBounds As GM_Rectangle_t, _ >>>> ByVal aLeftPixel As Int32, _ >>>> ByVal aTopPixel As Int32, _ >>>> ByVal aPixelWidth As Int32, _ >>>> ByVal aPixelHeight As Int32 _ >>>> ) As GM_Error_t32 >>>> ///// >>>> >>>> but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to >>>> the function in order to represent NULL) when the 5th argument was expecting the >>>> GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to >>>> draw all layers. So, I overloaded the function as such >>>> >>>> ///// >>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>> ( _ >>>> ByVal aDC As IntPtr, _ >>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>> ByVal aLayerCount As Int32, _ >>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>> ByVal aWorldBounds As IntPtr, _ >>>> ByVal aLeftPixel As Int32, _ >>>> ByVal aTopPixel As Int32, _ >>>> ByVal aPixelWidth As Int32, _ >>>> ByVal aPixelHeight As Int32 _ >>>> ) As GM_Error_t32 >>>> ///// >>>> >>>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it accepts a NULL >>>> argument for the 5th parameter in order to get the function to draw all layers. I >>>> suppose that's all well and good and everything seems to work fine, but the developer >>>> of the DLL - who admittedly is not a VB expert - thinks that there should be a better >>>> way to it in VB so that I don't have to duplicate the function prototypes (I would >>>> imagine some function prototypes would require more than just 1 overload. For >>>> example, I think I would need to overload the above function declare a couple of more >>>> times to account for the second argument - which can also receive NULL or a >>>> structure - and then any combination of the two arguments that can receive a NULL or >>>> structure.) Is there a more efficient way to go about this on my end? >>>> >>>> Thanks, >>>> Lance >>>> >>> >>> >> >> > > It looks like everything is an in parameter (hence no need for ByRef), or
does the C++ function use any of the parameters to return stuff? As Branco wrote you'll need to use a class since value types (i.e. structures) can't be null. If would define it like this: <StructLayout(LayoutKind.Sequential)> _ Public Class GM_Rectangle_t Public mMinX As Double Public mMinY As Double Public mMaxX As Double Public mMaxY As Double End Class Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ ( _ ByVal aDC As IntPtr, _ ByVal aLayerList As IntPtr, _ ByVal aLayerCount As Int32, _ ByVal aDrawFlags As Int32, _ ByVal aWorldBounds As GM_Rectangle_t, _ ByVal aLeftPixel As Int32, _ ByVal aTopPixel As Int32, _ ByVal aPixelWidth As Int32, _ ByVal aPixelHeight As Int32 _ ) As Int32 You wrote that you had problem converting to classes in some cases where you had structure members. There is probably a way out of that too, but I don't think any of this is actaully worth the effort. If you have something that already works (using overloads) then I would stick with that and not spend more time on this optimization. I'm sure you have plenty of other, more important things to do :-) Interesting problem none the less /claes Show quoteHide quote "Lance" <nu***@business.com> wrote in message news:%23xC71YhwGHA.2400@TK2MSFTNGP06.phx.gbl... > here are the definitions of the custom types in the C++ header file. > > ///// > typedef struct > { > double mMinX; // Minimum x/easting/longitude coordinate > double mMinY; // Minimum y/northing/latitude coordinate > double mMaxX; // Maximum x/easting/longitude coordinate > double mMaxY; // Maximum y/northing/latitude coordinate > } GM_Rectangle_t; > > typedef void* GM_LayerHandle_t32; > ///// > > and here are my .NET translations > ///// > Public Structure GM_Rectangle_t > Public mMinX As Double ' Minimum x/easting/longitude coordinate > Public mMinY As Double ' Minimum y/northing/latitude coordinate > Public mMaxX As Double ' Maximum x/easting/longitude coordinate > Public mMaxY As Double ' Maximum y/northing/latitude coordinate > End Structure > ///// > > for GM_LayerHandle_t32, on the advice of the SDK developer I've defined an > Alias as such: > > ///// > Imports GM_LayerHandle_t32 = System.Int32 > ///// > > Lance > > > "Claes Bergefall" <louplou@nospam.nospam> wrote in message > news:eEekqagwGHA.976@TK2MSFTNGP05.phx.gbl... >> Hmm, that's a new one. Can you post the definitions of the custom types >> (GM_Rectangle_t, GM_LayerHAndle_t32 etc), preferably both the C++ and the >> .NET code >> >> /claes >> >> "Lance" <nu***@business.com> wrote in message >> news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... >>> Changing it to >>> >>> ///// >>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>> ( _ >>> ByVal aDC As IntPtr, _ >>> ByRef aLayerList As GM_LayerHandle_t32, _ >>> ByVal aLayerCount As Int32, _ >>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>> ByVal aWorldBounds As GM_Rectangle_t, _ >>> ByVal aLeftPixel As Int32, _ >>> ByVal aTopPixel As Int32, _ >>> ByVal aPixelWidth As Int32, _ >>> ByVal aPixelHeight As Int32 _ >>> ) As GM_Error_t32 >>> ///// >>> >>> then sending "Nothing" (without the quotes, of course) as the 5th >>> argument results in a PInvokeStackImbalance. >>> >>> Lance >>> >>> >>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>> news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >>>> Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. >>>> No need to pass it by ref since it's an in parameter. Then just pass >>>> Nothing to it. >>>> >>>> /claes >>>> >>>> >>>> "Lance" <nu***@business.com> wrote in message >>>> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>>>> That is the question. >>>>> >>>>> In an unmanaged C++ DLL I'm making calls to, one of the function >>>>> prototypes is >>>>> >>>>> ///// >>>>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>>>> ( >>>>> HDC aDC, // Device context to draw to >>>>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for >>>>> all >>>>> uint32 aLayerCount, // Number of layers in list (0 for all) >>>>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is >>>>> performed >>>>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL >>>>> for all >>>>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>>>> sint32 aTopPixel, // Top pixel coordinate to draw to >>>>> sint32 aPixelWidth, // Width in pixels to draw >>>>> sint32 aPixelHeight // Height in pixels to draw >>>>> ); >>>>> ///// >>>>> which I originally translated to >>>>> >>>>> ///// >>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>>> ( _ >>>>> ByVal aDC As IntPtr, _ >>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>> ByVal aLayerCount As Int32, _ >>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>> ByRef aWorldBounds As GM_Rectangle_t, _ >>>>> ByVal aLeftPixel As Int32, _ >>>>> ByVal aTopPixel As Int32, _ >>>>> ByVal aPixelWidth As Int32, _ >>>>> ByVal aPixelHeight As Int32 _ >>>>> ) As GM_Error_t32 >>>>> ///// >>>>> >>>>> but I couldn't figure out how get it to receive NULL (I was sending >>>>> IntPtr.Zero to the function in order to represent NULL) when the 5th >>>>> argument was expecting the GM_Rectangle_t structure. NULL needs to be >>>>> sent to the function in order for it to draw all layers. So, I >>>>> overloaded the function as such >>>>> >>>>> ///// >>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>>> ( _ >>>>> ByVal aDC As IntPtr, _ >>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>> ByVal aLayerCount As Int32, _ >>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>> ByVal aWorldBounds As IntPtr, _ >>>>> ByVal aLeftPixel As Int32, _ >>>>> ByVal aTopPixel As Int32, _ >>>>> ByVal aPixelWidth As Int32, _ >>>>> ByVal aPixelHeight As Int32 _ >>>>> ) As GM_Error_t32 >>>>> ///// >>>>> >>>>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it >>>>> accepts a NULL argument for the 5th parameter in order to get the >>>>> function to draw all layers. I suppose that's all well and good and >>>>> everything seems to work fine, but the developer of the DLL - who >>>>> admittedly is not a VB expert - thinks that there should be a better >>>>> way to it in VB so that I don't have to duplicate the function >>>>> prototypes (I would imagine some function prototypes would require >>>>> more than just 1 overload. For example, I think I would need to >>>>> overload the above function declare a couple of more times to account >>>>> for the second argument - which can also receive NULL or a structure - >>>>> and then any combination of the two arguments that can receive a NULL >>>>> or structure.) Is there a more efficient way to go about this on my >>>>> end? >>>>> >>>>> Thanks, >>>>> Lance >>>>> >>>> >>>> >>> >>> >> >> > > Claes,
Thanks for all of your responses and for all of your help. Am I correct in interpreting your last message as advising me to use VB Classes for C++ types that can be passed as nulls? Or, we you advising me to stick with overloading? This particular function doesn't return anything into the structure, just an error code, so passing by value in this case is fine, as you said. Thanks again, Lance Show quoteHide quote "Claes Bergefall" <louplou@nospam.nospam> wrote in message news:ODllf2twGHA.4256@TK2MSFTNGP06.phx.gbl... > It looks like everything is an in parameter (hence no need for ByRef), or > does the C++ function use any of the parameters to return stuff? > As Branco wrote you'll need to use a class since value types (i.e. > structures) can't be null. If would define it like this: > > <StructLayout(LayoutKind.Sequential)> _ > Public Class GM_Rectangle_t > Public mMinX As Double > Public mMinY As Double > Public mMaxX As Double > Public mMaxY As Double > End Class > > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByVal aLayerList As IntPtr, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As Int32, _ > ByVal aWorldBounds As GM_Rectangle_t, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As Int32 > > You wrote that you had problem converting to classes in some cases where > you had structure members. There is probably a way out of that too, but I > don't think any of this is actaully worth the effort. If you have > something that already works (using overloads) then I would stick with > that and not spend more time on this optimization. I'm sure you have > plenty of other, more important things to do :-) > > Interesting problem none the less > > /claes > > "Lance" <nu***@business.com> wrote in message > news:%23xC71YhwGHA.2400@TK2MSFTNGP06.phx.gbl... >> here are the definitions of the custom types in the C++ header file. >> >> ///// >> typedef struct >> { >> double mMinX; // Minimum x/easting/longitude coordinate >> double mMinY; // Minimum y/northing/latitude coordinate >> double mMaxX; // Maximum x/easting/longitude coordinate >> double mMaxY; // Maximum y/northing/latitude coordinate >> } GM_Rectangle_t; >> >> typedef void* GM_LayerHandle_t32; >> ///// >> >> and here are my .NET translations >> ///// >> Public Structure GM_Rectangle_t >> Public mMinX As Double ' Minimum x/easting/longitude coordinate >> Public mMinY As Double ' Minimum y/northing/latitude coordinate >> Public mMaxX As Double ' Maximum x/easting/longitude coordinate >> Public mMaxY As Double ' Maximum y/northing/latitude coordinate >> End Structure >> ///// >> >> for GM_LayerHandle_t32, on the advice of the SDK developer I've defined >> an Alias as such: >> >> ///// >> Imports GM_LayerHandle_t32 = System.Int32 >> ///// >> >> Lance >> >> >> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >> news:eEekqagwGHA.976@TK2MSFTNGP05.phx.gbl... >>> Hmm, that's a new one. Can you post the definitions of the custom types >>> (GM_Rectangle_t, GM_LayerHAndle_t32 etc), preferably both the C++ and >>> the .NET code >>> >>> /claes >>> >>> "Lance" <nu***@business.com> wrote in message >>> news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... >>>> Changing it to >>>> >>>> ///// >>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>> ( _ >>>> ByVal aDC As IntPtr, _ >>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>> ByVal aLayerCount As Int32, _ >>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>> ByVal aWorldBounds As GM_Rectangle_t, _ >>>> ByVal aLeftPixel As Int32, _ >>>> ByVal aTopPixel As Int32, _ >>>> ByVal aPixelWidth As Int32, _ >>>> ByVal aPixelHeight As Int32 _ >>>> ) As GM_Error_t32 >>>> ///// >>>> >>>> then sending "Nothing" (without the quotes, of course) as the 5th >>>> argument results in a PInvokeStackImbalance. >>>> >>>> Lance >>>> >>>> >>>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>>> news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >>>>> Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. >>>>> No need to pass it by ref since it's an in parameter. Then just pass >>>>> Nothing to it. >>>>> >>>>> /claes >>>>> >>>>> >>>>> "Lance" <nu***@business.com> wrote in message >>>>> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>>>>> That is the question. >>>>>> >>>>>> In an unmanaged C++ DLL I'm making calls to, one of the function >>>>>> prototypes is >>>>>> >>>>>> ///// >>>>>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>>>>> ( >>>>>> HDC aDC, // Device context to draw to >>>>>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for >>>>>> all >>>>>> uint32 aLayerCount, // Number of layers in list (0 for all) >>>>>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is >>>>>> performed >>>>>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL >>>>>> for all >>>>>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>>>>> sint32 aTopPixel, // Top pixel coordinate to draw to >>>>>> sint32 aPixelWidth, // Width in pixels to draw >>>>>> sint32 aPixelHeight // Height in pixels to draw >>>>>> ); >>>>>> ///// >>>>>> which I originally translated to >>>>>> >>>>>> ///// >>>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" >>>>>> _ >>>>>> ( _ >>>>>> ByVal aDC As IntPtr, _ >>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>> ByVal aLayerCount As Int32, _ >>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>> ByRef aWorldBounds As GM_Rectangle_t, _ >>>>>> ByVal aLeftPixel As Int32, _ >>>>>> ByVal aTopPixel As Int32, _ >>>>>> ByVal aPixelWidth As Int32, _ >>>>>> ByVal aPixelHeight As Int32 _ >>>>>> ) As GM_Error_t32 >>>>>> ///// >>>>>> >>>>>> but I couldn't figure out how get it to receive NULL (I was sending >>>>>> IntPtr.Zero to the function in order to represent NULL) when the 5th >>>>>> argument was expecting the GM_Rectangle_t structure. NULL needs to >>>>>> be sent to the function in order for it to draw all layers. So, I >>>>>> overloaded the function as such >>>>>> >>>>>> ///// >>>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" >>>>>> _ >>>>>> ( _ >>>>>> ByVal aDC As IntPtr, _ >>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>> ByVal aLayerCount As Int32, _ >>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>> ByVal aWorldBounds As IntPtr, _ >>>>>> ByVal aLeftPixel As Int32, _ >>>>>> ByVal aTopPixel As Int32, _ >>>>>> ByVal aPixelWidth As Int32, _ >>>>>> ByVal aPixelHeight As Int32 _ >>>>>> ) As GM_Error_t32 >>>>>> ///// >>>>>> >>>>>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it >>>>>> accepts a NULL argument for the 5th parameter in order to get the >>>>>> function to draw all layers. I suppose that's all well and good and >>>>>> everything seems to work fine, but the developer of the DLL - who >>>>>> admittedly is not a VB expert - thinks that there should be a better >>>>>> way to it in VB so that I don't have to duplicate the function >>>>>> prototypes (I would imagine some function prototypes would require >>>>>> more than just 1 overload. For example, I think I would need to >>>>>> overload the above function declare a couple of more times to account >>>>>> for the second argument - which can also receive NULL or a >>>>>> structure - and then any combination of the two arguments that can >>>>>> receive a NULL or structure.) Is there a more efficient way to go >>>>>> about this on my end? >>>>>> >>>>>> Thanks, >>>>>> Lance >>>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> >> > > I was just thinking that trying to get away from the overloading that
already works might not be the most productive way of spending your time. As for classes vs structures, you will need to use classes if you need to be able to pass null values. A value type cannot be null. Feel free to post the other structures that you had problems with if you're determined to go this way Does the code below work btw? /claes Show quoteHide quote "Lance" <chuckyboy81070-at-onehotpotatoimeanhotmail.com> wrote in message news:uQI$dguwGHA.4944@TK2MSFTNGP02.phx.gbl... > Claes, > > Thanks for all of your responses and for all of your help. Am I correct > in interpreting your last message as advising me to use VB Classes for C++ > types that can be passed as nulls? Or, we you advising me to stick with > overloading? > > This particular function doesn't return anything into the structure, just > an error code, so passing by value in this case is fine, as you said. > > Thanks again, > Lance > > > > "Claes Bergefall" <louplou@nospam.nospam> wrote in message > news:ODllf2twGHA.4256@TK2MSFTNGP06.phx.gbl... >> It looks like everything is an in parameter (hence no need for ByRef), or >> does the C++ function use any of the parameters to return stuff? >> As Branco wrote you'll need to use a class since value types (i.e. >> structures) can't be null. If would define it like this: >> >> <StructLayout(LayoutKind.Sequential)> _ >> Public Class GM_Rectangle_t >> Public mMinX As Double >> Public mMinY As Double >> Public mMaxX As Double >> Public mMaxY As Double >> End Class >> >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByVal aLayerList As IntPtr, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As Int32, _ >> ByVal aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As Int32 >> >> You wrote that you had problem converting to classes in some cases where >> you had structure members. There is probably a way out of that too, but I >> don't think any of this is actaully worth the effort. If you have >> something that already works (using overloads) then I would stick with >> that and not spend more time on this optimization. I'm sure you have >> plenty of other, more important things to do :-) >> >> Interesting problem none the less >> >> /claes >> >> "Lance" <nu***@business.com> wrote in message >> news:%23xC71YhwGHA.2400@TK2MSFTNGP06.phx.gbl... >>> here are the definitions of the custom types in the C++ header file. >>> >>> ///// >>> typedef struct >>> { >>> double mMinX; // Minimum x/easting/longitude coordinate >>> double mMinY; // Minimum y/northing/latitude coordinate >>> double mMaxX; // Maximum x/easting/longitude coordinate >>> double mMaxY; // Maximum y/northing/latitude coordinate >>> } GM_Rectangle_t; >>> >>> typedef void* GM_LayerHandle_t32; >>> ///// >>> >>> and here are my .NET translations >>> ///// >>> Public Structure GM_Rectangle_t >>> Public mMinX As Double ' Minimum x/easting/longitude coordinate >>> Public mMinY As Double ' Minimum y/northing/latitude coordinate >>> Public mMaxX As Double ' Maximum x/easting/longitude coordinate >>> Public mMaxY As Double ' Maximum y/northing/latitude coordinate >>> End Structure >>> ///// >>> >>> for GM_LayerHandle_t32, on the advice of the SDK developer I've defined >>> an Alias as such: >>> >>> ///// >>> Imports GM_LayerHandle_t32 = System.Int32 >>> ///// >>> >>> Lance >>> >>> >>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>> news:eEekqagwGHA.976@TK2MSFTNGP05.phx.gbl... >>>> Hmm, that's a new one. Can you post the definitions of the custom types >>>> (GM_Rectangle_t, GM_LayerHAndle_t32 etc), preferably both the C++ and >>>> the .NET code >>>> >>>> /claes >>>> >>>> "Lance" <nu***@business.com> wrote in message >>>> news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... >>>>> Changing it to >>>>> >>>>> ///// >>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>>>> ( _ >>>>> ByVal aDC As IntPtr, _ >>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>> ByVal aLayerCount As Int32, _ >>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>> ByVal aWorldBounds As GM_Rectangle_t, _ >>>>> ByVal aLeftPixel As Int32, _ >>>>> ByVal aTopPixel As Int32, _ >>>>> ByVal aPixelWidth As Int32, _ >>>>> ByVal aPixelHeight As Int32 _ >>>>> ) As GM_Error_t32 >>>>> ///// >>>>> >>>>> then sending "Nothing" (without the quotes, of course) as the 5th >>>>> argument results in a PInvokeStackImbalance. >>>>> >>>>> Lance >>>>> >>>>> >>>>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>>>> news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >>>>>> Change to ByVal aWorldBounds As GM_Rectangle_t in your first version. >>>>>> No need to pass it by ref since it's an in parameter. Then just pass >>>>>> Nothing to it. >>>>>> >>>>>> /claes >>>>>> >>>>>> >>>>>> "Lance" <nu***@business.com> wrote in message >>>>>> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>>>>>> That is the question. >>>>>>> >>>>>>> In an unmanaged C++ DLL I'm making calls to, one of the function >>>>>>> prototypes is >>>>>>> >>>>>>> ///// >>>>>>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>>>>>> ( >>>>>>> HDC aDC, // Device context to draw to >>>>>>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL >>>>>>> for all >>>>>>> uint32 aLayerCount, // Number of layers in list (0 for all) >>>>>>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is >>>>>>> performed >>>>>>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL >>>>>>> for all >>>>>>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>>>>>> sint32 aTopPixel, // Top pixel coordinate to draw to >>>>>>> sint32 aPixelWidth, // Width in pixels to draw >>>>>>> sint32 aPixelHeight // Height in pixels to draw >>>>>>> ); >>>>>>> ///// >>>>>>> which I originally translated to >>>>>>> >>>>>>> ///// >>>>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" >>>>>>> _ >>>>>>> ( _ >>>>>>> ByVal aDC As IntPtr, _ >>>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>>> ByVal aLayerCount As Int32, _ >>>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>>> ByRef aWorldBounds As GM_Rectangle_t, _ >>>>>>> ByVal aLeftPixel As Int32, _ >>>>>>> ByVal aTopPixel As Int32, _ >>>>>>> ByVal aPixelWidth As Int32, _ >>>>>>> ByVal aPixelHeight As Int32 _ >>>>>>> ) As GM_Error_t32 >>>>>>> ///// >>>>>>> >>>>>>> but I couldn't figure out how get it to receive NULL (I was sending >>>>>>> IntPtr.Zero to the function in order to represent NULL) when the 5th >>>>>>> argument was expecting the GM_Rectangle_t structure. NULL needs to >>>>>>> be sent to the function in order for it to draw all layers. So, I >>>>>>> overloaded the function as such >>>>>>> >>>>>>> ///// >>>>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" >>>>>>> _ >>>>>>> ( _ >>>>>>> ByVal aDC As IntPtr, _ >>>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>>> ByVal aLayerCount As Int32, _ >>>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>>> ByVal aWorldBounds As IntPtr, _ >>>>>>> ByVal aLeftPixel As Int32, _ >>>>>>> ByVal aTopPixel As Int32, _ >>>>>>> ByVal aPixelWidth As Int32, _ >>>>>>> ByVal aPixelHeight As Int32 _ >>>>>>> ) As GM_Error_t32 >>>>>>> ///// >>>>>>> >>>>>>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now >>>>>>> it accepts a NULL argument for the 5th parameter in order to get the >>>>>>> function to draw all layers. I suppose that's all well and good and >>>>>>> everything seems to work fine, but the developer of the DLL - who >>>>>>> admittedly is not a VB expert - thinks that there should be a better >>>>>>> way to it in VB so that I don't have to duplicate the function >>>>>>> prototypes (I would imagine some function prototypes would require >>>>>>> more than just 1 overload. For example, I think I would need to >>>>>>> overload the above function declare a couple of more times to >>>>>>> account for the second argument - which can also receive NULL or a >>>>>>> structure - and then any combination of the two arguments that can >>>>>>> receive a NULL or structure.) Is there a more efficient way to go >>>>>>> about this on my end? >>>>>>> >>>>>>> Thanks, >>>>>>> Lance >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> >> > > Thanks for clearing that up, Claies. And yes, the code you sent previously
did indeed work. Lance Show quoteHide quote "Claes Bergefall" <louplou@nospam.nospam> wrote in message news:%23yMneEvwGHA.5024@TK2MSFTNGP04.phx.gbl... >I was just thinking that trying to get away from the overloading that >already works might not be the most productive way of spending your time. > As for classes vs structures, you will need to use classes if you need to > be able to pass null values. A value type cannot be null. > > Feel free to post the other structures that you had problems with if > you're determined to go this way > Does the code below work btw? > > /claes > > "Lance" <chuckyboy81070-at-onehotpotatoimeanhotmail.com> wrote in message > news:uQI$dguwGHA.4944@TK2MSFTNGP02.phx.gbl... >> Claes, >> >> Thanks for all of your responses and for all of your help. Am I correct >> in interpreting your last message as advising me to use VB Classes for >> C++ types that can be passed as nulls? Or, we you advising me to stick >> with overloading? >> >> This particular function doesn't return anything into the structure, just >> an error code, so passing by value in this case is fine, as you said. >> >> Thanks again, >> Lance >> >> >> >> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >> news:ODllf2twGHA.4256@TK2MSFTNGP06.phx.gbl... >>> It looks like everything is an in parameter (hence no need for ByRef), >>> or does the C++ function use any of the parameters to return stuff? >>> As Branco wrote you'll need to use a class since value types (i.e. >>> structures) can't be null. If would define it like this: >>> >>> <StructLayout(LayoutKind.Sequential)> _ >>> Public Class GM_Rectangle_t >>> Public mMinX As Double >>> Public mMinY As Double >>> Public mMaxX As Double >>> Public mMaxY As Double >>> End Class >>> >>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >>> ( _ >>> ByVal aDC As IntPtr, _ >>> ByVal aLayerList As IntPtr, _ >>> ByVal aLayerCount As Int32, _ >>> ByVal aDrawFlags As Int32, _ >>> ByVal aWorldBounds As GM_Rectangle_t, _ >>> ByVal aLeftPixel As Int32, _ >>> ByVal aTopPixel As Int32, _ >>> ByVal aPixelWidth As Int32, _ >>> ByVal aPixelHeight As Int32 _ >>> ) As Int32 >>> >>> You wrote that you had problem converting to classes in some cases where >>> you had structure members. There is probably a way out of that too, but >>> I don't think any of this is actaully worth the effort. If you have >>> something that already works (using overloads) then I would stick with >>> that and not spend more time on this optimization. I'm sure you have >>> plenty of other, more important things to do :-) >>> >>> Interesting problem none the less >>> >>> /claes >>> >>> "Lance" <nu***@business.com> wrote in message >>> news:%23xC71YhwGHA.2400@TK2MSFTNGP06.phx.gbl... >>>> here are the definitions of the custom types in the C++ header file. >>>> >>>> ///// >>>> typedef struct >>>> { >>>> double mMinX; // Minimum x/easting/longitude coordinate >>>> double mMinY; // Minimum y/northing/latitude coordinate >>>> double mMaxX; // Maximum x/easting/longitude coordinate >>>> double mMaxY; // Maximum y/northing/latitude coordinate >>>> } GM_Rectangle_t; >>>> >>>> typedef void* GM_LayerHandle_t32; >>>> ///// >>>> >>>> and here are my .NET translations >>>> ///// >>>> Public Structure GM_Rectangle_t >>>> Public mMinX As Double ' Minimum x/easting/longitude coordinate >>>> Public mMinY As Double ' Minimum y/northing/latitude coordinate >>>> Public mMaxX As Double ' Maximum x/easting/longitude coordinate >>>> Public mMaxY As Double ' Maximum y/northing/latitude coordinate >>>> End Structure >>>> ///// >>>> >>>> for GM_LayerHandle_t32, on the advice of the SDK developer I've defined >>>> an Alias as such: >>>> >>>> ///// >>>> Imports GM_LayerHandle_t32 = System.Int32 >>>> ///// >>>> >>>> Lance >>>> >>>> >>>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>>> news:eEekqagwGHA.976@TK2MSFTNGP05.phx.gbl... >>>>> Hmm, that's a new one. Can you post the definitions of the custom >>>>> types (GM_Rectangle_t, GM_LayerHAndle_t32 etc), preferably both the >>>>> C++ and the .NET code >>>>> >>>>> /claes >>>>> >>>>> "Lance" <nu***@business.com> wrote in message >>>>> news:uPh0qGUwGHA.4944@TK2MSFTNGP02.phx.gbl... >>>>>> Changing it to >>>>>> >>>>>> ///// >>>>>> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" >>>>>> _ >>>>>> ( _ >>>>>> ByVal aDC As IntPtr, _ >>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>> ByVal aLayerCount As Int32, _ >>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>> ByVal aWorldBounds As GM_Rectangle_t, _ >>>>>> ByVal aLeftPixel As Int32, _ >>>>>> ByVal aTopPixel As Int32, _ >>>>>> ByVal aPixelWidth As Int32, _ >>>>>> ByVal aPixelHeight As Int32 _ >>>>>> ) As GM_Error_t32 >>>>>> ///// >>>>>> >>>>>> then sending "Nothing" (without the quotes, of course) as the 5th >>>>>> argument results in a PInvokeStackImbalance. >>>>>> >>>>>> Lance >>>>>> >>>>>> >>>>>> "Claes Bergefall" <louplou@nospam.nospam> wrote in message >>>>>> news:uLln65TwGHA.3508@TK2MSFTNGP04.phx.gbl... >>>>>>> Change to ByVal aWorldBounds As GM_Rectangle_t in your first >>>>>>> version. No need to pass it by ref since it's an in parameter. Then >>>>>>> just pass Nothing to it. >>>>>>> >>>>>>> /claes >>>>>>> >>>>>>> >>>>>>> "Lance" <nu***@business.com> wrote in message >>>>>>> news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... >>>>>>>> That is the question. >>>>>>>> >>>>>>>> In an unmanaged C++ DLL I'm making calls to, one of the function >>>>>>>> prototypes is >>>>>>>> >>>>>>>> ///// >>>>>>>> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >>>>>>>> ( >>>>>>>> HDC aDC, // Device context to draw to >>>>>>>> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL >>>>>>>> for all >>>>>>>> uint32 aLayerCount, // Number of layers in list (0 for all) >>>>>>>> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is >>>>>>>> performed >>>>>>>> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL >>>>>>>> for all >>>>>>>> sint32 aLeftPixel, // Left pixel coordinate to draw to >>>>>>>> sint32 aTopPixel, // Top pixel coordinate to draw to >>>>>>>> sint32 aPixelWidth, // Width in pixels to draw >>>>>>>> sint32 aPixelHeight // Height in pixels to draw >>>>>>>> ); >>>>>>>> ///// >>>>>>>> which I originally translated to >>>>>>>> >>>>>>>> ///// >>>>>>>> Public Declare Function GM_DrawLayerList Lib >>>>>>>> "GlobalMapperInterface" _ >>>>>>>> ( _ >>>>>>>> ByVal aDC As IntPtr, _ >>>>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>>>> ByVal aLayerCount As Int32, _ >>>>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>>>> ByRef aWorldBounds As GM_Rectangle_t, _ >>>>>>>> ByVal aLeftPixel As Int32, _ >>>>>>>> ByVal aTopPixel As Int32, _ >>>>>>>> ByVal aPixelWidth As Int32, _ >>>>>>>> ByVal aPixelHeight As Int32 _ >>>>>>>> ) As GM_Error_t32 >>>>>>>> ///// >>>>>>>> >>>>>>>> but I couldn't figure out how get it to receive NULL (I was sending >>>>>>>> IntPtr.Zero to the function in order to represent NULL) when the >>>>>>>> 5th argument was expecting the GM_Rectangle_t structure. NULL >>>>>>>> needs to be sent to the function in order for it to draw all >>>>>>>> layers. So, I overloaded the function as such >>>>>>>> >>>>>>>> ///// >>>>>>>> Public Declare Function GM_DrawLayerList Lib >>>>>>>> "GlobalMapperInterface" _ >>>>>>>> ( _ >>>>>>>> ByVal aDC As IntPtr, _ >>>>>>>> ByRef aLayerList As GM_LayerHandle_t32, _ >>>>>>>> ByVal aLayerCount As Int32, _ >>>>>>>> ByVal aDrawFlags As GM_DrawFlags_t32, _ >>>>>>>> ByVal aWorldBounds As IntPtr, _ >>>>>>>> ByVal aLeftPixel As Int32, _ >>>>>>>> ByVal aTopPixel As Int32, _ >>>>>>>> ByVal aPixelWidth As Int32, _ >>>>>>>> ByVal aPixelHeight As Int32 _ >>>>>>>> ) As GM_Error_t32 >>>>>>>> ///// >>>>>>>> >>>>>>>> Note the change to "ByVal" and "IntPtr" for the 5th argument. Now >>>>>>>> it accepts a NULL argument for the 5th parameter in order to get >>>>>>>> the function to draw all layers. I suppose that's all well and >>>>>>>> good and everything seems to work fine, but the developer of the >>>>>>>> DLL - who admittedly is not a VB expert - thinks that there should >>>>>>>> be a better way to it in VB so that I don't have to duplicate the >>>>>>>> function prototypes (I would imagine some function prototypes would >>>>>>>> require more than just 1 overload. For example, I think I would >>>>>>>> need to overload the above function declare a couple of more times >>>>>>>> to account for the second argument - which can also receive NULL or >>>>>>>> a structure - and then any combination of the two arguments that >>>>>>>> can receive a NULL or structure.) Is there a more efficient way to >>>>>>>> go about this on my end? >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Lance >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>>> >>> >>> >> >> > > Well drat...if Claes and the other handful of aces here are stumped, then I guess it's
safe to assume that a better solution than overloading is likely non-existent. I know, it's only been about 5 or 6 hours since the original posting, but I can tell when no ones biting! Overloading it is, then. Lance Show quoteHide quote "Lance" <nu***@business.com> wrote in message news:uGExAfTwGHA.4880@TK2MSFTNGP04.phx.gbl... > That is the question. > > In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is > > ///// > GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList > ( > HDC aDC, // Device context to draw to > GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all > uint32 aLayerCount, // Number of layers in list (0 for all) > GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed > const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all > sint32 aLeftPixel, // Left pixel coordinate to draw to > sint32 aTopPixel, // Top pixel coordinate to draw to > sint32 aPixelWidth, // Width in pixels to draw > sint32 aPixelHeight // Height in pixels to draw > ); > ///// > which I originally translated to > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByRef aWorldBounds As GM_Rectangle_t, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the > function in order to represent NULL) when the 5th argument was expecting the > GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to draw > all layers. So, I overloaded the function as such > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aWorldBounds As IntPtr, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > Note the change to "ByVal" and "IntPtr" for the 5th argument. Now it accepts a NULL > argument for the 5th parameter in order to get the function to draw all layers. I > suppose that's all well and good and everything seems to work fine, but the developer of > the DLL - who admittedly is not a VB expert - thinks that there should be a better way > to it in VB so that I don't have to duplicate the function prototypes (I would imagine > some function prototypes would require more than just 1 overload. For example, I think > I would need to overload the above function declare a couple of more times to account > for the second argument - which can also receive NULL or a structure - and then any > combination of the two arguments that can receive a NULL or structure.) Is there a more > efficient way to go about this on my end? > > Thanks, > Lance > Lance wrote:
Show quoteHide quote > That is the question. <snip>> > In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is > > ///// > GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList > ( > HDC aDC, // Device context to draw to > GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all > uint32 aLayerCount, // Number of layers in list (0 for all) > GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed > const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all > sint32 aLeftPixel, // Left pixel coordinate to draw to > sint32 aTopPixel, // Top pixel coordinate to draw to > sint32 aPixelWidth, // Width in pixels to draw > sint32 aPixelHeight // Height in pixels to draw > ); > ///// > which I originally translated to > > ///// > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ > ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByRef aWorldBounds As GM_Rectangle_t, _ > ByVal aLeftPixel As Int32, _ > ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// > > but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the > function in order to represent NULL) when the 5th argument was expecting the > GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to draw > all layers. Without knowing how the type GM_Rectangle_t is declared, I'll risk suggesting that instead of a structure, you declare it as a Class with fixed layout (using the StructLayout(LayoutKind.Sequential) attribute): <StructLayout(LayoutKind.Sequential)> Class GM_Rectangle_t Public Left As Integer Public Top As Integer '... etc End Class Then you'd change de function declaration to: > Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ ByVal aWorldBounds As GM_Rectangle_t, _> ( _ > ByVal aDC As IntPtr, _ > ByRef aLayerList As GM_LayerHandle_t32, _ > ByVal aLayerCount As Int32, _ > ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aLeftPixel As Int32, _ and just pass Nothing when you wanted to pass Null.> ByVal aTopPixel As Int32, _ > ByVal aPixelWidth As Int32, _ > ByVal aPixelHeight As Int32 _ > ) As GM_Error_t32 > ///// HTH. Regards, Branco This seems to work. I'm curious to know if i should now start from scratch and translate
all of the C custom types into classes instead of structures. What would be the benefits (besides not needing to overload functions that use the custom types as arguments) and drawbacks, if any? Lance Show quoteHide quote "Branco Medeiros" <branco.medei***@gmail.com> wrote in message news:1155794161.803322.295710@h48g2000cwc.googlegroups.com... > > Lance wrote: >> That is the question. >> >> In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is >> >> ///// >> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >> ( >> HDC aDC, // Device context to draw to >> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all >> uint32 aLayerCount, // Number of layers in list (0 for all) >> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed >> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all >> sint32 aLeftPixel, // Left pixel coordinate to draw to >> sint32 aTopPixel, // Top pixel coordinate to draw to >> sint32 aPixelWidth, // Width in pixels to draw >> sint32 aPixelHeight // Height in pixels to draw >> ); >> ///// >> which I originally translated to >> >> ///// >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ >> ByRef aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// >> >> but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the >> function in order to represent NULL) when the 5th argument was expecting the >> GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to >> draw >> all layers. > <snip> > > Without knowing how the type GM_Rectangle_t is declared, I'll risk > suggesting that instead of a structure, you declare it as a Class with > fixed layout (using the StructLayout(LayoutKind.Sequential) attribute): > > <StructLayout(LayoutKind.Sequential)> Class GM_Rectangle_t > Public Left As Integer > Public Top As Integer > '... etc > End Class > > Then you'd change de function declaration to: > >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// > > and just pass Nothing when you wanted to pass Null. > > HTH. > > Regards, > > Branco > I went ahead and convert a handful of the structures to classes. I was having some
problems, though. It looks as though I'm not allowed to easily convert structures that contain other structures to classes. Well, I may be allowed, but it's causing other problems with marshalling and pointers, and I'm not good at all dealing with those. Anyway, I can't find out a solution to that one, so for the time being, I've got a mix of classes (that contain only Enums or native data types) and structures. You know what? It just occurred to me that all of this work - converting some of the stuff to classes and leaving others as structures - hasn't actually helped me with my original post: finding an alternative to overloading. Don't get me wrong, I certainly appreciate the help. Given what I'm realistically able to divulge in a newsgroup post code-wise, you guys are doing your best to help me, I know. Thanks again, and if you guys have any more suggestions, I'm all ears. Show quoteHide quote "Branco Medeiros" <branco.medei***@gmail.com> wrote in message news:1155794161.803322.295710@h48g2000cwc.googlegroups.com... > > Lance wrote: >> That is the question. >> >> In an unmanaged C++ DLL I'm making calls to, one of the function prototypes is >> >> ///// >> GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_DrawLayerList >> ( >> HDC aDC, // Device context to draw to >> GM_LayerHandle_t32* aLayerList, // List of layers to draw or NULL for all >> uint32 aLayerCount, // Number of layers in list (0 for all) >> GM_DrawFlags_t32 aDrawFlags, // Flags controlling how the draw is performed >> const GM_Rectangle_t* aWorldBounds, // World bounds to draw or NULL for all >> sint32 aLeftPixel, // Left pixel coordinate to draw to >> sint32 aTopPixel, // Top pixel coordinate to draw to >> sint32 aPixelWidth, // Width in pixels to draw >> sint32 aPixelHeight // Height in pixels to draw >> ); >> ///// >> which I originally translated to >> >> ///// >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ >> ByRef aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// >> >> but I couldn't figure out how get it to receive NULL (I was sending IntPtr.Zero to the >> function in order to represent NULL) when the 5th argument was expecting the >> GM_Rectangle_t structure. NULL needs to be sent to the function in order for it to >> draw >> all layers. > <snip> > > Without knowing how the type GM_Rectangle_t is declared, I'll risk > suggesting that instead of a structure, you declare it as a Class with > fixed layout (using the StructLayout(LayoutKind.Sequential) attribute): > > <StructLayout(LayoutKind.Sequential)> Class GM_Rectangle_t > Public Left As Integer > Public Top As Integer > '... etc > End Class > > Then you'd change de function declaration to: > >> Public Declare Function GM_DrawLayerList Lib "GlobalMapperInterface" _ >> ( _ >> ByVal aDC As IntPtr, _ >> ByRef aLayerList As GM_LayerHandle_t32, _ >> ByVal aLayerCount As Int32, _ >> ByVal aDrawFlags As GM_DrawFlags_t32, _ > ByVal aWorldBounds As GM_Rectangle_t, _ >> ByVal aLeftPixel As Int32, _ >> ByVal aTopPixel As Int32, _ >> ByVal aPixelWidth As Int32, _ >> ByVal aPixelHeight As Int32 _ >> ) As GM_Error_t32 >> ///// > > and just pass Nothing when you wanted to pass Null. > > HTH. > > Regards, > > Branco > Lance wrote:
> I went ahead and convert a handful of the structures to classes. I was having some Notice that when a structure 'contains' another, such as:> problems, though. It looks as though I'm not allowed to easily convert structures that > contain other structures to classes. Well, I may be allowed, but it's causing other > problems with marshalling and pointers, and I'm not good at all dealing with those. > Anyway, I can't find out a solution to that one, so for the time being, I've got a mix of > classes (that contain only Enums or native data types) and structures. structure A Dim W As Integer DIm X As Integer End Structure Structure B Dim Y As A Dim Z As Integer End Structure it means that the fields of the contained structure are linearlly layed out onto the container structure (this is true for C, C++ and VB as well). In the example above, the physical layout of B would be similar to: Structure C Dim Y_W As Integer Dim Y_X As Integer Dim Z As Integer End Structure On the other side, when you declare a class member, be it part of a structure or another class, just the reference to the class is part of the container, not the actual "structure" of the class. Therefore, in your particular case, where should you use classes instead of structures? Whenever you had a *pointer* to a structure. In this case it's best to use classes, because the .Net marshaller will know what to do with it. So If you had (forgive my C): typedef struct { int F1; int F2; } T1; typedef struct { T1 FT1; int F3; } T2; typedef struct { T1* pFT1; T2 FT2; } T3 void DoIt(T3* pT3) { .... } Then I *guess* you'd have to declare (in the VB side) both a structure and a class to represent, respectivelly, the structures and *the pointers* to the structures: Public Structure T1 Dim F1 As Integer Dim F2 As Integer End Structure <StructLayout(LayoutKind.Sequential)> Class PtrT1 Public Value As T1 End Class Structure T2 Dim FT1 As T1 Dim F3 As Integer End Structure Structure T3 Dim pFT1 As PtrT1 Dim FT2 As T2 End Struct <StructLayout(LayoutKind.Sequential)> Class PtrT3 Public Value As T3 End Class Declare Sub DoIt Lib "whatever.dll" (ByVal pT3 As PtrT3) I'm not sure if declaring the actual structures as values inside the classes (as I showed above) will do. In a worst case, you'll have to be explicit (I hope not), such as in: <StructLayout(LayoutKind.Sequential)> Class PtrT3b Public pFT1 As PtrT1 Public FT2_FT1_F1 As Integer Public FT2_FT1_F2 As Integer Public FT2_F3 As Integer End Class I guess you got the idea... HTH. Regards, Branco. That makes sense to me. Thanks for your help Branco.
Lance Show quoteHide quote "Branco Medeiros" <branco.medei***@gmail.com> wrote in message news:1155935489.585980.10730@p79g2000cwp.googlegroups.com... > Lance wrote: >> I went ahead and convert a handful of the structures to classes. I was >> having some >> problems, though. It looks as though I'm not allowed to easily convert >> structures that >> contain other structures to classes. Well, I may be allowed, but it's >> causing other >> problems with marshalling and pointers, and I'm not good at all dealing >> with those. >> Anyway, I can't find out a solution to that one, so for the time being, >> I've got a mix of >> classes (that contain only Enums or native data types) and structures. > > Notice that when a structure 'contains' another, such as: > > structure A > Dim W As Integer > DIm X As Integer > End Structure > > Structure B > Dim Y As A > Dim Z As Integer > End Structure > > it means that the fields of the contained structure are linearlly layed > out onto the container structure (this is true for C, C++ and VB as > well). In the example above, the physical layout of B would be similar > to: > > Structure C > Dim Y_W As Integer > Dim Y_X As Integer > Dim Z As Integer > End Structure > > On the other side, when you declare a class member, be it part of a > structure or another class, just the reference to the class is part of > the container, not the actual "structure" of the class. > > Therefore, in your particular case, where should you use classes > instead of structures? Whenever you had a *pointer* to a structure. In > this case it's best to use classes, because the .Net marshaller will > know what to do with it. > > So If you had (forgive my C): > > typedef struct { > int F1; > int F2; > } T1; > > typedef struct { > T1 FT1; > int F3; > } T2; > > typedef struct { > T1* pFT1; > T2 FT2; > } T3 > > void DoIt(T3* pT3) { > ... > } > > Then I *guess* you'd have to declare (in the VB side) both a structure > and a class to represent, respectivelly, the structures and *the > pointers* to the structures: > > Public Structure T1 > Dim F1 As Integer > Dim F2 As Integer > End Structure > > <StructLayout(LayoutKind.Sequential)> > Class PtrT1 > Public Value As T1 > End Class > > Structure T2 > Dim FT1 As T1 > Dim F3 As Integer > End Structure > > Structure T3 > Dim pFT1 As PtrT1 > Dim FT2 As T2 > End Struct > > <StructLayout(LayoutKind.Sequential)> > Class PtrT3 > Public Value As T3 > End Class > > Declare Sub DoIt Lib "whatever.dll" (ByVal pT3 As PtrT3) > > I'm not sure if declaring the actual structures as values inside the > classes (as I showed above) will do. In a worst case, you'll have to be > explicit (I hope not), such as in: > > <StructLayout(LayoutKind.Sequential)> > Class PtrT3b > Public pFT1 As PtrT1 > Public FT2_FT1_F1 As Integer > Public FT2_FT1_F2 As Integer > Public FT2_F3 As Integer > End Class > > I guess you got the idea... > > HTH. > > Regards, > > Branco. >
ANN: VS.NET 2003 SP1
Memory Usange In VB.NET Serial Port Communuciation in VB with Compact Framework 2.0 Capturing the second column data from a list view box. create a folder useing vb code? Automaticaly Clicking a Checkbox on a webbrowser control hyperlink text ISDATE() took 8 seconds to complete ? client side dataset and dataset force immediate VS05 compile? |
|||||||||||||||||||||||