IntPtr and API functions
-
Hi. I'm not sure whether or not this thread should go here or over in the API section, except that it involves declarations that are definitely vb.Net. Anyway, my questions revolve around the use of IntPtr. My first thought was that since I needed to pass pointers to win32 functions, I needed to restrict myself to 32bit values. Therefore, it seems that IntPtr is only applicable when on a 32bit system. If a pointer is declared as IntPtr on a 64bit system, vb.Net is clever enough to make IntPtr fit the 64bitwidth of the current system. That makes it unusable for win32 functions because they can only deal with 32bit values. So then I thought, well, I'll switch to using UInt32, so that the API is accessible with a 32bit pointer. But then I thought, hm, that would be fine as far as the API function is concerned, but would create a problem when an API function returns a 32bit encoded address to a memory location on a 64bit system! So that seems to suggest that when you get the pointer out of the function, that it needs to be widened to a 64bit pointer so that the data there can be properly found and retrieved. So my questions are: 1. Is this logic basically correct? 2. Is IntPtr really nothing more than UInt32 or UInt64, depending on the bitwidth of the system? 3. Again, if all of this is correct, is casting or marshaling required to narrow and widen the pointer when a conversion is necessary?
-
Hi. I'm not sure whether or not this thread should go here or over in the API section, except that it involves declarations that are definitely vb.Net. Anyway, my questions revolve around the use of IntPtr. My first thought was that since I needed to pass pointers to win32 functions, I needed to restrict myself to 32bit values. Therefore, it seems that IntPtr is only applicable when on a 32bit system. If a pointer is declared as IntPtr on a 64bit system, vb.Net is clever enough to make IntPtr fit the 64bitwidth of the current system. That makes it unusable for win32 functions because they can only deal with 32bit values. So then I thought, well, I'll switch to using UInt32, so that the API is accessible with a 32bit pointer. But then I thought, hm, that would be fine as far as the API function is concerned, but would create a problem when an API function returns a 32bit encoded address to a memory location on a 64bit system! So that seems to suggest that when you get the pointer out of the function, that it needs to be widened to a 64bit pointer so that the data there can be properly found and retrieved. So my questions are: 1. Is this logic basically correct? 2. Is IntPtr really nothing more than UInt32 or UInt64, depending on the bitwidth of the system? 3. Again, if all of this is correct, is casting or marshaling required to narrow and widen the pointer when a conversion is necessary?
-
The
IntPtr
type will be 32 or 64 bits wide, as necessary, based on the target platform specified in the compiler options.Use the best guess
Then if the target system is 64bit, conversion of data types will be necessary between that and the 32bit pointers required by win32, if I understand things correctly. So I can use UInt32 for a passed argument to the API and widen that on output from the API to UInt64. Which would require marshaling, correct?
-
Then if the target system is 64bit, conversion of data types will be necessary between that and the 32bit pointers required by win32, if I understand things correctly. So I can use UInt32 for a passed argument to the API and widen that on output from the API to UInt64. Which would require marshaling, correct?
-
No, I already understand that part. The problem is that win32 API functions canNOT switch automatically...They're stuck in 32bit land. So it seems that conversion IS necessary when on a 64bit system right? Also, just realized this morning, that for some API functions, it needs to be Int32 not UInt32, since some functions return an address of -1 on failure. Theoretically, it is the only negative number that would be returned, so this SHOULD be OK. This whole thing bothers me though, because it means that any pointer that can be passed to a win32 function is stuck in the 32bit range of values. Although it would OK to widen this to 64bits after output from the function, by placing zeroes in the higher order 32 bits, it does not guarantee that a "low" 32bit address is even available. The only reason that might not be a problem is that a 32bit number is still awfully large and how many 32bit valid addresses ranges (blocks of memory) can you expect to be using during any Windows session, even with multitasking? But on the other hand, is the bit order correct in an Int32 to be used directly as a pointer on a 64bit system, without having to convert to Int64? I am having return value problems in my functions and if I can put the addressing thing to rest, then I can move on to other culprits.
-
No, I already understand that part. The problem is that win32 API functions canNOT switch automatically...They're stuck in 32bit land. So it seems that conversion IS necessary when on a 64bit system right? Also, just realized this morning, that for some API functions, it needs to be Int32 not UInt32, since some functions return an address of -1 on failure. Theoretically, it is the only negative number that would be returned, so this SHOULD be OK. This whole thing bothers me though, because it means that any pointer that can be passed to a win32 function is stuck in the 32bit range of values. Although it would OK to widen this to 64bits after output from the function, by placing zeroes in the higher order 32 bits, it does not guarantee that a "low" 32bit address is even available. The only reason that might not be a problem is that a 32bit number is still awfully large and how many 32bit valid addresses ranges (blocks of memory) can you expect to be using during any Windows session, even with multitasking? But on the other hand, is the bit order correct in an Int32 to be used directly as a pointer on a 64bit system, without having to convert to Int64? I am having return value problems in my functions and if I can put the addressing thing to rest, then I can move on to other culprits.
-
treddie wrote:
They're stuck in 32bit land.
No, they are rebuilt for 64 bit, which is why the
IntPtr
type is provided.Use the best guess