PixelAddress in 64 bit programs
Applies to: DicomObjects - COM Version (version 6)
Although all DICOM related maths in DicomObjects has always been 64-bit clean internally, the problem becomes apparent when addresses beyond the 32 bit/4 GigaByte limit are actually used for data objects, and when pointers to those objects are then passed via COM interfaces. Whilst it is possible to reproduce the problems under Windows 7 & 8, in practice they appear to occur more readily on Windows 10, probably due to address space layout randomization. They can show up as 3 similar but independent issues:
1) The PixelAddress method of DicomImage only returns a 4 byte integer, and thus cannot hold a full 64 bit address. In order to maintain backwards compatibility (and to conform to Visual Studio’s need for 32 and 64 bit versions to have identical type libraries), we have decided to leave the existence and signature of that method unchanged, but for it to throw an exception if used in 64 bit mode. For 64 bit programs we have added PixelAddress64 which returns an 8 byte integer, which can be cast to a full 64 bit pointer.
2) Errors are seen when one of the few other methods (such as MemoryImport & MemoryExport) which explicitly use the OLE_HANDLE data type to pass a reference to memory are used, and that memory address is >4GByte. Unfortunately, the OLE_HANDLE type is still defined in the COM interface specification to be 32 bit, even in 64 bit builds, and as a result these methods are not reliable in a 64 bit version. None of these methods are commonly used, probably even less so in 64 bit applications, and so, for now, the interface has been left unchanged, but they are explicitly disabled in the 64 bit version, so that any failures will be visible during testing, rather than occurring semi-randomly in real use. In version 7, these will be re-factored into 64 bit clean interfaces, but if you find that you need any of these in your current code, please let us know, and a workaround, similar to that described above for PixelAddress can be arranged.
3) When references to DICOM objects are passed as parameters to other methods (e.g. adding a DicomDataSets collection as a sequence via DIcomAttributes.Add(….)), then the call will fail if the address of the object passed is actually beyond the 4 GigaByte limit.
As well as fixing these issues, we have undertaken a thorough code review, which has covered all the potential uses of 64 bit pointers and we believe that the 64 bit version is now “64 bit clean”. The first version to have the issues fixed is 220.127.116.11, and we would recommend that all installations using the 64 bit COM version should be upgraded as soon as possible. Issue (3) is resolved “silently” by the new version, but if you use the PixelAddress property, then you will need to re-import the type library, change to PixelAddress64, and then recompile.
Please contact firstname.lastname@example.org if you have any questions about this approach.