473,503 Members | 1,656 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

To overload, or not to overload?

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
Aug 16 '06 #1
14 1130
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.comwrote in message
news:uG**************@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

Aug 16 '06 #2
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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
news:uG**************@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


Aug 16 '06 #3
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

"Lance" <nu***@business.comwrote in message
news:uG**************@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

Aug 16 '06 #4

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

Aug 17 '06 #5
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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
news:uG**************@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



Aug 17 '06 #6
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" <lo*****@nospam.nospamwrote in message
news:eE*************@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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
news:uG**************@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



Aug 17 '06 #7
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

"Branco Medeiros" <br*************@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.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

Aug 17 '06 #8
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.

"Branco Medeiros" <br*************@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.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

Aug 17 '06 #9
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.comwrote in message
news:%2****************@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" <lo*****@nospam.nospamwrote in message
news:eE*************@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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
news:uG**************@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
>




Aug 18 '06 #10
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" <lo*****@nospam.nospamwrote in message
news:OD**************@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.comwrote in message
news:%2****************@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" <lo*****@nospam.nospamwrote in message
news:eE*************@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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
news:uG**************@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
>>
>
>




Aug 18 '06 #11
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.comwrote in message
news:uQ**************@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" <lo*****@nospam.nospamwrote in message
news:OD**************@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.comwrote in message
news:%2****************@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" <lo*****@nospam.nospamwrote in message
news:eE*************@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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
news:uL**************@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.comwrote in message
>news:uG**************@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
>>>
>>
>>
>
>




Aug 18 '06 #12
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.

Aug 18 '06 #13
Thanks for clearing that up, Claies. And yes, the code you sent previously
did indeed work.

Lance

"Claes Bergefall" <lo*****@nospam.nospamwrote in message
news:%2****************@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.comwrote in message
news:uQ**************@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" <lo*****@nospam.nospamwrote in message
news:OD**************@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.comwrote in message
news:%2****************@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" <lo*****@nospam.nospamwrote in message
news:eE*************@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.comwrote in message
news:uP**************@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" <lo*****@nospam.nospamwrote in message
>news:uL**************@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.comwrote in message
>>news:uG**************@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
>>>>
>>>
>>>
>>
>>
>
>




Aug 20 '06 #14
That makes sense to me. Thanks for your help Branco.

Lance

"Branco Medeiros" <br*************@gmail.comwrote in message
news:11*********************@p79g2000cwp.googlegro ups.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.

Aug 20 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2039
by: Piotre Ugrumov | last post by:
I'm following your help. I have written the overload of the operator <<. This overload work! :-) But I have some problem with the overload of the operator >>. I have written the overload of this...
3
2221
by: Piotre Ugrumov | last post by:
I have done the overload on the operator >> and << in the class Attore. These 2 overload work correctly. I have done the overload of the same overload in the class Film. The class film ha inside...
17
2478
by: Chris | last post by:
To me, this seems rather redundant. The compiler requires that if you overload the == operator, you must also overload the != operator. All I do for the != operator is something like this: ...
9
2366
by: Tony | last post by:
I have an operator== overload that compares two items and returns a new class as the result of the comparison (instead of the normal bool) I then get an ambiguous operater compile error when I...
5
3676
by: jknupp | last post by:
In the following program, if the call to bar does not specify the type as <int>, gcc gives the error "no matching function for call to ‘bar(A&, <unresolved overloaded function type>)’". Since bar...
0
7198
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7072
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7271
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7319
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
4666
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3160
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3149
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1498
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
373
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.