ThinkGeo.com    |     Blog    |     Wiki    |     Support

Weird problem with COM Interop

Hi,


I've been experimenting the last few days with the trial version of Map Suite Geocoder (version 4.5.0.0) and everything was going fine until I decided to test the reverse geocoding feature. When I tried to match a latitude/longitude my host application would totally crash. I am using the geocoder in a COM object so I can expose its features to a Win32 application. The reverse geocoding works fine when I try it under the sample applications you provide.


The weird thing is that if I use a street address in the Match method then it is working fine but as soon as I use coordinates it crashes. I've tested my COM Object on two different computers (one with Vista, the other with Win XP) and both experienced the same problem. On top of that, if I access my COM Object via a VB script is working fine even with the coordinates match string. Kind of crazy..


I have attached a zip file with all the projects and the VB script so you can give it a try and maybe figure out what is causing the problem. I've reduced the COM Object interface to the minimum so you can test it.


To summarize:

Geocoder is being used in an assembly which is being used for COM Interop. The assembly is being registered using the RegAsm utlity with the /codebase /tlb options.


COM Object is being used by a Delphi 7 application. Type library is being imported by Delphi 7.


USAGeocoder.Match crashes when trying to match a string with coordinates, e.g. usaGeocoder.Match("42.020431 -87.666757"), but works fine when trying to match a street name, e.g. usaGeocoder.Match("5300 N Winthrop Ave").


Uses .NET Framework 3.5 (I've also tried to recompile using Framework 4 with the same results). My assembly was compiled using MS Visual C# 2010 Express.


Let me know if you need more info. Thanks..


Regards,

Kostas

 



001_Geocoder_COM_Interop.zip (408 KB)

Kostas,


Thanks for your post,


I tested your sample application using the latest MapSuiteGeocoder version, it works fine! Here is my test result below:



The latest MapSuiteGeocoder version is 4.5.53.0, in this version we fixed several issues and added some new features please contact ThinkGeo support to get the latest version to try again,


Thanks,


Scott,



Hi Scott, 
  
 Thanks for checking it out. Only the Delphi test client was having the problem. The C# test client and the VB script were executing fine.  Have you tried with the Delphi test executable (Project1.exe) as well? 
  
 Regards, 
 Kostas 


Kostas, 



This is weird, it goes well for VBS / .NET Client but not for Delphi. I reviewed the source code of Geocode and there is no special code for the Reverse Geocode branch, so weird.
It’s not convenient for us to test though as we don’t have the Delphi environment. You can try to locate the problem like this.



1, Instead of using the class USAGeocoder, you can use the CoordinatesMatchingPlugin for the Reverse Geocoder and see if the issue still exists:


CoordinatesMatchingPlugin plugin = new CoordinatesMatchingPlugin(@"C:\Program Files (x86)\ThinkGeo\Map Suite Geocoder Evaluation Edition 4.5\HowDoISamples\SampleData\ChicagoData");
plugin.Open();
Collection<GeocoderMatch> matchResult = plugin.Match("42.020431 -87.666757");
plugin.Close();



2, Create your own sub class by inheriting CoordinatesMatchingPlugin, and call base class’s method, 


   class MyCoordinatesMatchingPlugin : CoordinatesMatchingPlugin
    {
        public MyCoordinatesMatchingPlugin(string dataFolder)
            : base(dataFolder)
        { }

        protected override Collection<string> FormalizeCore(string sourceText)
        {
     return base. FormalizeCore (sourceText);
        }

        protected override Collection<GeocoderMatch> MatchCore(string sourceText)
        {
            return base.MatchCore(sourceText);
        }

        protected override void OpenCore()
        {
            base.OpenCore();
        }
}

And try the code in the 1st part (with MyCoordinateMatchingPlugin this time) again, the issue should still exist.



3, replace the default implementation of the override methods one by one, and check if it will work fine after overriding one method. E.g, here we override the FormalizeCore method, if the issue is gone after this change, we can see some codes in base.FormalizeCore leads to this problem.

  protected override Collection<string> FormalizeCore(string sourceText)
        {
            Collection<string> result = new Collection<string>();
            result.Add("42.020431 -87.666757");
            return result;
        }


In this way we can locate which method the issue is locating, and we can have another review on that method. 



Let me know what you find out, as well as any suggestions for locating this issue.



Thanks,



Ben

Hi Ben,


I followed your suggestions and I created a sub class.. I have also added messages in each method implementation so I can see which methods is being called..


When used with all test client the method sequence is a) Creator, b) Open Core, c) Formalize Core and d) Match Core



Delphi test client will crash after the Match Core call


Here is my sub class clode:


 



    internal class MyCoordinatesMatchingPlugin : CoordinatesMatchingPlugin
    {
        public MyCoordinatesMatchingPlugin(string dataFolder)
            : base(dataFolder)
        {
            MessageBox.Show("Creator");
        
        }

        protected override Collection<string> FormalizeCore(string sourceText)
        {
            MessageBox.Show("Formalize Core");

            Collection<string> result = new Collection<string>();
            result.Add("42.010431 -87.666757");
            return result;
        }

        protected override Collection<GeocoderMatch> MatchCore(string sourceText)
        {
            MessageBox.Show("Match Core");

            return base.MatchCore(sourceText);
        }

        protected override void OpenCore()
        {
            MessageBox.Show("Open Core");

            base.OpenCore();
        }
    }
Regards,

Kostas



Kostas, 
  
 I checked the MatchCore function in the CoordinateMatchingPlugin class, I guessed maybe there are two things caused the crash problem in the Delphi program, one is the Linq implemention, another is the RTree implemention, the RTree implemention is the key function for the ReverseGeocode so I cannot change it anything, I just removed the Linq implemention and use a general function to instead of it. Also I tested the search result and performance, it is exact the same as the previous version. So please contact ThinkGeo Support to get the latest version and try it in your Delphi program again. 
  
 If you still encounter any crash problems in your Delphi program please send the crash message to us so that we can see where is the exact problem in the core code, 
  
 Thanks, 
  
 Scott,

Scott,


I've tried the latest version you suggested but unfortunately I get the same result. I've attached 2 screenshots, one with the exception message and the other with the location of the exception. I don't know if these are helpful.




I've tried also to call my COM Object using late binding but got the same result so I guess that rules out any issues with the type library. Is it possible for someone over there to try to create a test application in another Win32 language (not .NET), like C++ or VB and try use my COM object and see if anything happens?


Happy New Year :)


Regards,

Kostas


 


 



Exception.jpg (13.9 KB)
001_CPU.jpg (92.9 KB)

Kostas, 
  
 I would like to ask you did you try to use the early binding, from your screen shots I cannot found out any useful information, currently I just guessed where is the reason in the Geocoder core, did you install the .NET Framework 3.5 more higher version on your local machine, if not, please install the .NET Framework 3.5 or higher version to try again, because we used many technologies of .NET Framework 3.5. 
  
 Thanks, 
  
 Scott,

Scott, 
  
 I get the same screenshot no matter if it’s early or late binding. I had already installed all the .NET Frameworks from 1.0 to 4.0 so there is no issue with that. 
  
 Thanks, 
 Kostas 


Kostas, 
  
 Thanks for your responses, I checked all the posts above, there is one thing need to confirm with you, was this problem only exist in the reverse geocoding? The geocoding is successful in your application, is that true? If that, I’m  afraid of the crash problem is from the RTree component, in our reverse geocoding we use the RTree component to locate the zip code area so that we can find out the enter coordinate in a small range such as a zipcode area. I checked all the source code for the reverse geocoding, there are not any doubtful codes can cause the crash problem, in the previous version we have changed the Linq implemention and use general code to implement it. So I believe this is the only reason can cause your crash problem in your application.  
  
 We will have a discussion about it to see are there any work around for your application. 
  
 Thanks, 
  
 Scott,

Scott, 
  
 This problem exists *only* in reverse geocoding (e.g. entering coordinates as a search string in the UsaGeocoder.Match mehod). Normal geocoding works fine. 
  
 FYI, if I use my COM object via a VBScript in my Delphi application (by using the MS Script Control object) then it works fine. That’s the only workaround I have found so far. 
  
 Thanks, 
 Kostas 


Kostas,


I have a suggestion to you and need your helps to validte the crash problem is either in the RTree functionality or the other places, because we don't have the Delphi environment so please create another new sample application and reference the MapSuiteCore.dll, then copy the following code to your new sample application:


 


 



RtreeSpatialIndex rtreeIndex = new RtreeSpatialIndex(Path.Combine(dataFilePath, "rt2.idx"));
rtreeIndex.Open();
Dictionary<string, RECTANGLE_D> streetsInsideZip = rtreeIndex.GetRecordByBoundingBoxIndexesContainingRectangle(upperLeftX, lowerRightY,lowerRightX, upperLeftY);
rtreeIndex.Close();
You can specify the upperLeftX, LowerRightY, LowerRightX, upperLeftY values by yourself, we just need to validate the rtree functionality. This is a simple sample and we use this function in MapSuiteGeocoder core code for reverse geocoding, also when you use this sample code above please through the COM methods to reference the MapSuiteCore.dll so that we can find out the crash reason.


Thanks,


Scott,



Scott, 
  
 Referencing the MapSuiteCore.dll will give me an error when I try to build my assembly (for COM interop) because the MapSuiteCore.dll is not signed with a strong key. You provide a version with a strong key sign for the MapSuiteGeocoder but not for the MapSuiteCore. Unless I am missing something. 
  
 Regards, 
 Kostas 


Kostas,


We have two versions for each product, one is Geocoder general version, another is Geocoder string named version, here is the screen shot in the zip file of MapSuiteGeocoder dll package below:



Please reference the MapSuiteGeocoder.dll in the Geocoder folder and make a simple sample according to my code to check the Rtree component in your Delphi application.

 


If you have any questions please let me know,


Thanks,


Scott,


 



Scott, 
  
 I cannot use the RtreeSpatialIndex class unless I reference the MapSuiteCore.dll as well. Doing so will lead to the problem I mentioned in my last message. The exact message I get from the compiler is “Assembly generation failed – Referenced assembly ‘MapSuiteCore’ does not have a strong name” 
  
 Regards, 
 Kostas 
  
  
  
  

Kostas,


I'm sorry I made a mistake for you, I meant that you need to reference the MapSuiteCore.dll without strong named, in the ServicesEdition dll package there are also two folders below:



Open the Services Edition(Not Services Edition- Strong Named) folder then you can see the MapSuiteCore.dll that without strong named,  please reference this dll directly so the strong name issue in your application can be resolved correctly,


Thanks,


Scott,



Scott, 
  
 I can’t find those folders (Services Edition) in my “Map Suite Geocoder Full Edition 4.5” (evaluation) folder list. Any suggestion? 
  
 Thanks, 
 Kostas 


Kostas, 
  
 There is one thing need to confirm with you first, did you purchase the ServicesEdition? The MapSuiteCore.dll is belong to the ServicesEdition, therefore, you still can get it from this location: C:\Program Files\ThinkGeo\Map Suite Geocoder Full Edition 4.5\HowDoISamples\Dependencies\Desktop. 
  
 In this folder it includes all dlls for MapSuite DesktopEdition, you can just reference the MapSuiteCore.dll to try again, 
  
 Thanks, 
  
 Scott,

Scott,


My company has not bought the ServicesEdition. In fact we haven't bought anything yet as we are still evaluating the product. I have already tried to use the MapSuiteCore.dll under C:\Program Files\ThinkGeo\Map Suite Geocoder Full Edition 4.5\HowDoISamples\Dependencies\Desktop but this version is not signed with a strong key so I cannot use it. That's what I had said in previous messages.


Posted By Kostas on 01-12-2011 03:16 AM 



Referencing the MapSuiteCore.dll will give me an error when I try to build my assembly (for COM interop) because the MapSuiteCore.dll is not signed with a strong key. You provide a version with a strong key sign for the MapSuiteGeocoder but not for the MapSuiteCore. Unless I am missing something. 


Posted By Kostas on 01-12-2011 08:15 AM


I cannot use the RtreeSpatialIndex class unless I reference the MapSuiteCore.dll as well. Doing so will lead to the problem I mentioned in my last message. The exact message I get from the compiler is "Assembly generation failed -- Referenced assembly 'MapSuiteCore' does not have a strong name" 


Since I am building an assembly for COM interop all assembiles referenced have to be strong signed, otherwise I cannot compile my project.


Thanks,

Kostas


 



Kostas, 
  
 So can you install the ServicesEdition Evaluation on your machine? Because we don’t have the Delphi envrionment so we just can track the crash problem in your side, we guessed there are two things maybe caused the crash problem, one is linq implemention, another is the Rtree queries, now we have removed the linq implemention from the core code, so we have to determine the problem is whether from the Rtree queries, in order to validate it you have to reference the MapSuiteCore.dll so please download and install the ServicesEdition and create a simple sample using the code what I posted,  
  
 If you have any issues about it please let us know, 
  
 Thanks, 
  
 Scott,