VB.net dll marshalling Com object

  • 12 years ago

    I have a 3rd party dll written for .net 2.0.  I have written a COM wrapper around this dll so that I can get to it's properties from a VB6 application.  The dll is responsible for geocoding an address.  When an address is geocoded it has a collection of stringbuilder objects that contain information about the address.  Two pieces of that information is the latitude and longitude of the address.

     Now when I call the wrapper from a .net application everything works fine.  When I call the wrapper from a VB6 application everything works fine 99% of the time.  Unfortunately there is a small set of addresses that when geocoded return nothing for the latitude longitude.  The programmer of the 3rd party dll says it's probably problems with marshalling.  However, if I geocode the address right next to one of the problem addresses the latitude and longitude are fine.  I can even enter an invalid address and let the dll get a closest match and it will send back the correct lat and lon for the problem address.

     Below is the code from the wrapper dll.  If anyone can help I would greatly appreciate it.

     

    Imports System

    Imports System.Collections

    Imports System.Text

    Imports Microsoft.VisualBasic.Compatibility

    Imports Geocode

    <ComClass(TSH_Geocoder.ClassId, TSH_Geocoder.InterfaceId, TSH_Geocoder.EventsId)> _

    Public Class TSH_Geocoder

    Public Const ClassId As String = "082FA870-90F7-43dd-B4E6-CDC01F2F8DAE"

    Public Const InterfaceId As String = "EB62B05F-B81E-48fc-AF1C-D665E9C8B05F"

    Public Const EventsId As String = "68D2BE67-8FC7-4ccd-984D-8A25B68B7183"

    Public Enum enumFindOption

    Standardize

    Geocode

    ZipLocation

    End Enum

    Public Enum enumMatchMode

    CASS

    Close

    Tight

    Extended

    PartialAddress

    End Enum

    Enum GeocodeValueIndices

    InputAddress

    InputHouseNmb

    StreetPrf

    StreetName

    StreeSff

    StreetType

    FloorAppt

    InputCity

    InputState

    InputZip5

    InputZip4

    StdAddress

    ErrorCode

    Accuracy

    MatchingAddress

    MatchingHouseMnb

    MatchingStreetName

    MatchingStreetType

    MatchingStreetPrf

    MatchingStreetSff

    MatchingCity

    MatchingStateAbbr

    MatchingZip5

    MatchingZip4

    Block

    COUSUB

    Place

    Longitude

    Latitude

    Tract70

    Tract80

    BG80

    BG90

    BlockGrp

    End Enum

    Dim foFindOption As enumFindOption = enumFindOption.Geocode

    Dim sAddressLine As String = String.Empty

    Dim sAddress As String = String.Empty

    Dim sLastLine As String = String.Empty

    Dim sCity As String = String.Empty

    Dim sState As String = String.Empty

    Dim sZip As String = String.Empty

    Dim sZip4 As String = String.Empty

    Dim sZip9 As String = String.Empty

    Dim sZip10 As String = String.Empty

    Dim dblLatitude As Double

    Dim dblLongitude As Double

    Dim sBlock As String = String.Empty

    Dim sLocationCode As String = String.Empty 'EE = Fail, AA = Rooftop, ZB = BG, ZA = BG, ZC = Zip

    Dim sLicenseFile As String = String.Empty 'Not used only here for backward compatability

    Dim sLicenseKey As String = String.Empty 'Not used only here for backward compatability

    Dim sSearchPath As String = String.Empty 'Not used only here for backward compatability

    Dim sZ9Filename As String = String.Empty 'Not used only here for backward compatability

    Dim sCarrt As String = String.Empty 'Carrier Route

    Dim nCensusIDFormat As Integer 'Backward Compatability

    Dim bIsLocal As Boolean 'Backward Compatability

    Dim nMatchMode As enumMatchMode 'Backward Compatability

    Dim bMultipleMatchEnable As Boolean 'Backward Compatability

    Dim sMatchCode As String = String.Empty

    Dim sErrorMessage As String = String.Empty

    Dim sLastValues As String = String.Empty

    'Match Codes

    '"00" "No address found by Geocoder."

    '"01" "Unresolved error occured."

    '"02" "Could Not find GSD file for that state."

    '"03" "Incorrect GSD file signature or version ID."

    '"04" "GSD file out of date."

    '"10" "No city, state or zip code was found."

    '"11" "Input zipcode was not in the directory."

    '"12" "Input city was not in the directory."

    '"13" "Input city was not unique in the directory."

    '"14" "Out of licensed area."

    '"20" "No matching streets found in directory."

    '"21" "No matching cross streets for an intersection match."

    '"22", "24" "No matching ranges"

    '"23" "Match is unresolved"

    '"25" "Too many cross streets for intersection matching."

    '"26" "No address found when attempting a multiline-match."

    '"27" "Unable to Parse Address"

    'Module level variables

    Dim mGeoCD As New Geocode.Geocoder 'this is the 3rd party dll reference

    Public Sub New()

    MyBase.New()

    End Sub

    'Open initializes the Geocoder

    Public Function Open(Optional ByVal sConfigFile As String = "GcdConfig.xml") As Boolean

    Dim bSuccess As Boolean

    Try

    If sConfigFile Is Nothing Then

    sConfigFile = "GcdConfig.xml"

    End If

    If mGeoCD Is Nothing Then

    mGeoCD = New Geocode.Geocoder

    End If

    bSuccess = mGeoCD.Open(sConfigFile)

    If Not bSuccess Then

    sErrorMessage = "Failed to Open Geocoder: " & mGeoCD.ErrMsg

    Else

    mGeoCD.SetRunFlags([Shared].Common.FLAGS_TRY_PLACE_ZIPS Or _

    [Shared].Common.FLAGS_NO_PARITY_CHK Or _

    [Shared].Common.FLAGS_FUZZY_RANGE Or _

    [Shared].Common.FLAGS_FUZZY_TYPE Or _

    [Shared].Common.FLAGS_FUZZY_DIR Or _

    [Shared].Common.FLAGS_FUZZY_STREET)

    'mGeoCD.SetRunFlags( _

    ' [Shared].Common.FLAGS_NO_PARITY_CHK Or _

    ' [Shared].Common.FLAGS_FUZZY_RANGE Or _

    ' [Shared].Common.FLAGS_FUZZY_TYPE Or _

    ' [Shared].Common.FLAGS_FUZZY_DIR Or _

    '[Shared].Common.FLAGS_FUZZY_STREET)

    End If

    Catch ex As System.Exception

    'Failure

    bSuccess = False

    sErrorMessage = ex.ToString

    End Try

    Return bSuccess

    End Function

    'Find Geocodes the according to properties set before hand

    Public Function Find() As Boolean

    Dim bFound As Boolean

    Try

    Dim sAddress As String = String.Empty

    Dim sParseAddress() As String

     

    'If LastLine(city, state zip) is used use address/addressline with lastline

    If LastLine.Trim.Length > 0 Then 'use the Address and LastLine property

    If Address.Trim.Length > 0 Then

    sAddress = Address.Trim & ", " & LastLine.Trim

    ElseIf sAddressLine.Trim.Length > 0 Then

    sAddress = AddressLine.Trim & ", " & LastLine.Trim

    Else

    sAddress = LastLine.Trim

    End If

    Else 'use address/addressline, city, state, zip

    '[Addr|AddrLine][, City][, state][ zip]

    If AddressLine.Trim.Length > 0 Then 'use addressline, city, state, zip

    sAddress = AddressLine.Trim

    ElseIf Address.Trim.Length > 0 Then

    sAddress = Address.Trim

    Else 'do not set sAddress

    End If

    If sCity.Trim.Length > 0 Then

    sAddress &= IIf(sAddress.Trim.Length > 0, ", ", String.Empty) & sCity.Trim

    End If

    If sState.Trim.Length > 0 Then

    sAddress &= IIf(sAddress.Trim.Length > 0, ", ", String.Empty) & sState.Trim

    End If

    If sZip.Trim.Length > 0 Then

    sAddress &= IIf(sAddress.Trim.Length > 0, " ", String.Empty) & sZip.Trim

    End If

    End If

    Dim bSuccess As Boolean

    bSuccess = mGeoCD.ProcessAddress(sAddress)

    If bSuccess Then

    mGeoCD.LastResultBestMatch()

    End If

    If (Not bSuccess) And Me.FindOption = enumFindOption.ZipLocation Then

    mGeoCD.PushParserData()

    mGeoCD.UseCentroid()

    mGeoCD.PopParserData()

    If ((1 << [Shared].AccuracyCodes.ZIP_CENTROID) And mGeoCD.AccuracyFlags) = _

    (1 << [Shared].AccuracyCodes.ZIP_CENTROID) Then

    bSuccess = True

    Else

    bSuccess = False

    End If

    End If

    If bSuccess Then

    Dim smsg As New StringBuilder()

    For i As Integer = 0 To mGeoCD.Count - 1

    ' Data extraction loop.

    smsg.Append(String.Format("{0, 2} : {1,-11} = {2}", i, mGeoCD.Names(i), mGeoCD.Values(i)) & vbCrLf)

    Next

    'Here is where I get the problem.  when called from a .net app the value that corresponds to the Longitude and 'Latitude contains the correct latitude and longitude however when called from a VB6 app the longitude and 'latitude are empty.  The values property is a collection of stringbuilder objects. 

    MsgBox(smsg.ToString)

    Latitude = Val(mGeoCD.Values(GeocodeValueIndices.Latitude).ToString)

    Longitude = Val(mGeoCD.Values(GeocodeValueIndices.Longitude).ToString)

    'The Block Group

    Block = mGeoCD.Values(GeocodeValueIndices.BlockGrp).ToString

    If Me.FindOption = enumFindOption.ZipLocation Then

    LocationCode = "ZZ"

    bFound = True

    ElseIf CBool(1 << [Shared].AccuracyCodes.EXACT And mGeoCD.AccuracyFlags) Then

    'Rooftop

    LocationCode = "AA"

    bFound = True

     

    ElseIf CBool(1 << [Shared].AccuracyCodes.CLOSEST_ADDRESS And mGeoCD.AccuracyFlags) _

    Or CBool(1 << [Shared].AccuracyCodes.STREET_END And mGeoCD.AccuracyFlags) _

    Or CBool(1 << [Shared].AccuracyCodes.NO_PARITY And mGeoCD.AccuracyFlags) Then

    'Blockgroup

    LocationCode = "ZB"

    bFound = True

    ElseIf CBool(((1 << [Shared].AccuracyCodes.ZIP_CENTROID) And mGeoCD.AccuracyFlags)) Or _

    CBool((1 << [Shared].AccuracyCodes.PLACE_BASED_ZIP And mGeoCD.AccuracyFlags)) Then

    'ZIP Centroid

    LocationCode = "ZZ"

    bFound = True

     

    ElseIf CBool(1 << [Shared].AccuracyCodes.DIRECTION_CORRECTED And mGeoCD.AccuracyFlags) Or _

    CBool(1 << [Shared].AccuracyCodes.FUZZY_STREET_TYPE And mGeoCD.AccuracyFlags) Or _

    CBool(1 << [Shared].AccuracyCodes.PHONETIC_STREET_MATCH And mGeoCD.AccuracyFlags) Or _

    CBool(1 << [Shared].AccuracyCodes.SPELLING_CORRECTED And mGeoCD.AccuracyFlags) Then

    'Rooftop

    LocationCode = "AA"

    bFound = True

    Else

    'No Match

    LocationCode = "E"

    MatchCode = "27"

    bFound = False

     

    sErrorMessage = "Couldn't reconcile Accuracy Flags: " & mGeoCD.AccuracyFlags.ToString & vbCrLf & _

    "Accuracy Message: " & mGeoCD.AccMsg & vbCrLf & _

    "Accuracy Tags: " & mGeoCD.AccTagList.ToString & vbCrLf & _

    "Errors: " & mGeoCD.ErrMsg

    End If

    Else

    LocationCode = "E"

    MatchCode = "27"

    sErrorMessage = mGeoCD.ErrMsg & vbCrLf & mGeoCD.AccMsg

    End If

    If LocationCode = "AA" Then

    'Build the Standardized Address

    Dim sStreetPrefix As String = mGeoCD.Values(GeocodeValueIndices.MatchingStreetPrf).ToString.Trim

    Dim sStreet As String = mGeoCD.Values(GeocodeValueIndices.MatchingStreetName).ToString.Trim

    Dim sStreetSuffix As String = mGeoCD.Values(GeocodeValueIndices.MatchingStreetSff).ToString.Trim

    Dim sHouseNumber As String = mGeoCD.Values(GeocodeValueIndices.MatchingHouseMnb).ToString.Trim

    Dim sStreetType As String = mGeoCD.Values(GeocodeValueIndices.MatchingStreetType).ToString.Trim

    sAddress = sHouseNumber

    If sStreetPrefix.Length Then

    sAddress &= " " & sStreetPrefix

    End If

    If sStreet.Length Then

    sAddress &= " " & sStreet

    End If

    If sStreetType.Length Then

    sAddress &= " " & sStreetType

    End If

    If sStreetSuffix.Length Then

    sAddress &= " " & sStreetSuffix

    End If

    sAddressLine = sAddress

    ' Address = mGeoCD.Values(GeocodeValueIndices.MatchingHouseMnb).ToString & _

    ' " " & mGeoCD.Values(GeocodeValueIndices.MatchingStreetName).ToString & _

    ' " " & mGeoCD.Values(GeocodeValueIndices.MatchingStreetType).ToString

    Me.Address = sAddress

    Me.AddressLine = sAddress

    'Standardized City, State, Zip, Zip4, Zip9, Zip10

    MatchCode = "S" 'Standardized

    City = mGeoCD.Values(GeocodeValueIndices.MatchingCity).ToString

    State = mGeoCD.Values(GeocodeValueIndices.MatchingStateAbbr).ToString

    Zip = mGeoCD.Values(GeocodeValueIndices.MatchingZip5).ToString

    Zip4 = mGeoCD.Values(GeocodeValueIndices.MatchingZip4).ToString

    If Zip4.Length > 0 Then

    Zip9 = Zip & Zip4

    Zip10 = Zip &
    "-" & Zip4

    Else

    Zip9 = Zip

    Zip10 = Zip

    End If

    End If

    Catch ex As System.Exception

    Dim sValues As New StringBuilder

    For n As Integer = 0 To mGeoCD.Count - 1

    sValues.Append(mGeoCD.Names(n).ToString)

    sValues.Append(
    ": ")

    sValues.Append(mGeoCD.Values(n).ToString)

    sValues.Append(vbCrLf)

    Next

    sErrorMessage = "Unexpected Error: " & ex.ToString & _

    vbCrLf & "Geolytics Error Message: " & mGeoCD.ErrMsg & vbCrLf & _

    "Name/Value Pairs" & vbCrLf & _

    sValues.ToString()

    LocationCode = "E"

    MatchCode = "27"

    bFound = False

    End Try

    Return bFound

    End Function

     

    End Class

Post a reply

No one has replied yet! Why not be the first?

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“I invented the term Object-Oriented, and I can tell you I did not have C++ in mind.” - Alan Kay