Background:
Through single-step debugging last week, we found the small differences between the Open Source library mdcm and DCMTK in JPEG lossless compression for DICOM images, the DICOM image is successfully compressed in the C ++ and C # environments. However, the problem arises one after another. As the project goes deeper, it is found that the mdcm version that can be implemented in a separate test project has encountered an unexpected error after it is embedded into the entire project, the JPEG lossless compression of DICOM images is not implemented smoothly. Therefore, we need to continue the detailed comparison and analysis of mdcm and DCMTK to find the cause.
Problem Analysis:
After the project log function is enabled, the following information is returned:
No registered codec for transfer syntax! In DICOM. Data. dcmdataset. changetransfersyntax (dicomtransfersyntax newtransfersyntax, dcmcodecparameters parameters .............................. .
According to the log feedback, the registration of JPEG encoder fails. While the encoder part is included in the mdcm open source LibraryDICOM. codec64.dll assembly. Therefore, go to the debug page to check whether the project is loaded successfully.DICOM. codec64.dll Module.
The first step is to test the standalone project called jpeglossless last week. call DICOM in CS. codec. dicomcodec. registercodecs (); enables the program to enter dicomcodec. CS file. The program runs to the static method registercodecs of the static class dicomcodec.
As shown in, registercodecs successfully identifiedDICOM. DL assemblyAndDICOM. codec64.dll assembly.
Next, debug the program in a single step to the overall project, and transfer the program from the main framework to the call DICOM. codec. dicomcodec. registercodecs () that we manually add; function, as shown in:
After several debugging, we found that the JPEG encoder was not successfully registered using the registercodecs function, and only DICOM. DLL modules were identified in the 17 programs. By browsing the source code of the dicomcodec. CS file, it is found that the registercodecs function is a static function of the static class dicomcodec, which implements automatic registration of all JPEG encoders. The static class dicomcodec has other similar functions, such as public static void registercodec (dicomtransfersyntax ts, type); and public static void registerexternalcodecs (string path, string pattern ); the two functions register the decoder for the specified transport semantics and register the decoder for the assembly in the specified path. Because the registercodecs function is not used to automatically load the JPEG decoder, And the dicomcodec64.dll assembly has been added to the project, and the Module window of vs2012 shows that the dicomcodec64.dll assembly has been successfully loaded at the time of debugging. Therefore, we decided to manually load the dicomcodec64.dll Assembly, that is, replace the original DICOM. codec. dicomcodec. registercodecs (); statement with the following code,
String Path = system. Io. Directory. getcurrentdirectory ();
String Pattern = "DICOM. codec64.dll ";
Dicomcodec. registerexternalcodecs (path, pattern );
At this moment, the single-step debugging shows that the registration of the JPEG decoder in the dicomcodec64.dll program has been successful, and the integration of the DICOM image JPEG compression function with the overall project has been completed.
Summary: 1) Can the getreferencedassemblies function return all referenced assemblies in the project?
By comparingAutomaticAndManualIn the end, the getexportedtypes function is used to complete registration. The specific code is type [] types = ASM. getexportedtypes (); to extract the corresponding decoder. The only difference is that assemblyname [] referenced = Main. getreferencedassemblies (); extracts the referenced assembly of this module, while manual registration uses the assembly. is the getreferencedassemblies function a problem when the LoadFile function loads the specified Assembly file manually? Can the getreferencedassemblies function return all referenced assembly in our project?
Search for the functions of the getreferencedassemblies function on msdn. The descriptions are as follows:GetsAssemblynameObjects for all the Assemblies referenced by this Assembly.
At first glance, it seems that this function can return the names of all loaded assemblies in our project. But after careful analysis, what is mentioned in the description is"This Assembly", Here this should refer to the Assembly that calls the retreferencedassemblies function. Therefore, this function should obtain all the Assembly referenced by the current module, it is not the reference assembly of the entire project that we initially thought. After a long search, finally in a stackoverflow blog (http://stackoverflow.com/questions/3971793/what-when-assembly-getreferencedassemblies-returns-exe-dependency) found the relevant description of "extract all the dependent assembly of the project", the author not only gives the implementation method, it also gives the reason why the getreferencedassemblies function does not return all referenced assembly in the project (http://msdn.microsoft.com/en-us/magazine/cc163641.aspx ). Here, we will briefly summarize it and borrow the original author's diagram:
As shown in, if we call the getreferencedassemblies function in module A, the function should returnThis --Assembly B, C, and D referenced (directly applied. However, as shown on the left, assembly C and D reference other assemblies respectively, so we did not directly obtain all the assemblies in the project. Therefore, the DICOM. codec64 assembly we need is not returned smoothly during automatic loading.
Speaking of this, I thinkExtract all referenced assembly of the projectThe simplest method is that we can call the first return value of getreferencedassemblies recursively, so we can naturally get all the reference assembly a-J. However, in the blog post, the author extracts all referenced assembly from the right, because recursion affects program performance, especially when many program modules exist. In short, we use the"Forward TraversalTo extract all referenced assembly. The specific code can be downloaded from the reference blog.
2) Static Class C # And Singleton Design Mode
After comparing the source code registered by the mdcm and DCMTK open-source libraries for JPEG decoders, we found that in the DCMTK open-source library completed with C ++, the dcmcodeclist class in the singleton design mode is used to register various JPEG decoders. The mdcm open source library written in C # uses the static class public static dicomcodec of C. These two methods can achieve the same function. Since the first change from C ++ to C #, the difference between the two is not very clear, so I searched for it, only some important parts are extracted and pasted in the blog for future reference.
【Abstract】 1 ]:Http://bbs.csdn.net/topics/370008452
Apart from cross-assembly boundary issues, there is no essential difference between the static class and a single piece that imitates gof C ++. I am interested in discussing whether the two have achieved the same effect while meeting the same motivation. My personal opinion is that static classes have a simple and elegant side. In fact, in terms of Java and C #, there is a problem with the gof design pattern. This is the classic double lock check problem (see CLR via C #).
Roughly speaking, in C #4, these patterns disappear: single piece (static class), Policy (delegate and lambda), observer (event), decoration (Extension Method) factory (partially implemented by reflection), proxy (Expression Tree and dynamic class), iterator (yield return syntax), etc. If you follow gof implementation to do this, instead, you have gone far.
Finally, not only Singleton, but a general view of design patterns is that with the development of programming languages, the implementation of all design patterns will die out, and the ideas will be preserved. The essence of the design model can also be said to modify the defects of the language. It is an elegant language that does not require a design model. (This idea was put forward by one of my college students, he is also an expert in the Ruby community ).
【Abstract】 2 ]:Http://www.cnblogs.com/utopia/archive/2010/03/02/1676390.html
The semantics of a static class is a globally unique code segment, and the semantics of a single piece is a globally unique object instance;
The semantics is completely different. We can't say that the modifier is "globally unique", so we can put a comparison;
If so, we don't have to repeat all the public modifier items;
In addition, if you want to study object design, leave the code aside. Object design is an expression of philosophy and world view.
It is the essence of Object design to restore and express the real things with concepts. Code is a tool that reflects the conceptual model in your mind.
【Abstract ]:Http://blog.csdn.net/lyrebing/article/details/1902235
The purpose of Singleton mode is to provide a unique instance of the class in the program and only provide a unique access point. Static instances are not required. Only one global function is provided. The use of a single instance can inherit and implement interfaces, but the static class cannot. The static method cannot be an instance field in the response class, because the static method is not accessed through an instance. The method in the single instance can access the instance field in the unique instance. After a static method is executed, all objects created by it are released. The methods in the singleton can be retained. Static fields only provide global functions. You can share the same memory location. The field in the access ticket is a field in the unique instance of the class. You can only access the field of this instance.
[Email protected]
Time: 2014-08-17