我可以使用进程间通信在64位python中调用此32位dll吗?

时间:2019-03-29 11:36:51

标签: python ctypes 32bit-64bit

我需要从64位python调用32位dll,而我在使用进程间通信查找良好示例时遇到了麻烦。我不需要传递或返回任何复杂的东西。该dll用于corpscon,它将坐标转换为不同的系统。是否有包装32位dll的最佳方法。我看了看MSLoadlib,但无法理解如何用MSLoadlib加载dll。

这是代码,

from ctypes import *
import os

def conCoords(sysOutNum,outdatyear,outzonecode,inX,inY,inZ):
    corpslib = windll.LoadLibrary("C:\Program Files\CORPSCON6\corpscon_v6.dll")
    test00 = corpslib.corpscon_default_config()
    SetNadconPath = corpslib.SetNadconPath
    SetVertconPath = corpslib.SetVertconPath
    SetGeoidPath = corpslib.SetGeoidPath
    SetInSystem = corpslib.SetInSystem
    SetOutSystem = corpslib.SetOutSystem
    SetInDatum = corpslib.SetInDatum
    SetOutDatum = corpslib.SetOutDatum
    SetInZone = corpslib.SetInZone
    SetOutZone = corpslib.SetOutZone
    SetInUnits = corpslib.SetInUnits
    SetOutUnits = corpslib.SetOutUnits
    SetInVDatum = corpslib.SetInVDatum
    SetOutVDatum = corpslib.SetOutVDatum
    SetInVUnits = corpslib.SetInVUnits
    SetOutVUnits = corpslib.SetOutVUnits
    SetGeoidCodeBase = corpslib.SetGeoidCodeBase
    SetXIn = corpslib.SetXIn
    SetYIn = corpslib.SetYIn
    SetZIn = corpslib.SetZIn
    GetXOut = corpslib.GetXOut
    GetYOut = corpslib.GetYOut
    GetZOut = corpslib.GetZOut

    import ctypes

    SetNadconPath.argtypes = [ctypes.c_char_p]
    SetNadconPath.retval = [ctypes.c_int]
    SetVertconPath.argtypes = [ctypes.c_char_p]
    SetVertconPath.retval = [ctypes.c_int]
    SetGeoidPath.argtypes = [ctypes.c_char_p]
    SetGeoidPath.retval = [ctypes.c_int]
    SetInSystem.argtypes = [ctypes.c_int]  
    SetInSystem.retval = [ctypes.c_int]  
    SetInDatum.argtypes = [ctypes.c_int]  
    SetInDatum.retval = [ctypes.c_int]  
    SetOutDatum.argtypes = [ctypes.c_int]
    SetOutDatum.retval = [ctypes.c_int]
    SetOutSystem.argtypes = [ctypes.c_int]  
    SetOutSystem.retval = [ctypes.c_int]  
    SetInZone.argtypes = [ctypes.c_int]      
    SetInZone .retval = [ctypes.c_int]  
    SetOutZone.argtypes = [ctypes.c_int]    
    SetOutZone .retval = [ctypes.c_int] 
    SetInUnits.argtypes = [ctypes.c_int]  
    SetInUnits .retval = [ctypes.c_int]   
    SetInVDatum.argtypes = [ctypes.c_int]     
    SetInVDatum .retval = [ctypes.c_int]     
    SetOutVDatum.argtypes = [ctypes.c_int]    
    SetOutVDatum .retval =[ctypes.c_int]    
    SetInVUnits.argtypes = [ctypes.c_int]   
    SetInVUnits .retval = [ctypes.c_int]   
    SetOutVUnits.argtypes = [ctypes.c_int]    
    SetOutVUnits .retval = [ctypes.c_int]  
    SetGeoidCodeBase.argtypes = [ctypes.c_int]    
    SetGeoidCodeBase.retval = [ctypes.c_int]  
    SetXIn.argtypes = [ctypes.c_double]  
    SetXIn.retval = [ctypes.c_int]  
    SetYIn.argtypes = [ctypes.c_double]  
    SetYIn.retval = [ctypes.c_int]  
    SetZIn.argtypes = [ctypes.c_double]  
    SetZIn.retval = [ctypes.c_int]  
    GetXOut.retval =[ctypes.c_double]  
    GetYOut.retval =[ctypes.c_double]  
    GetZOut.retval = [ctypes.c_double]  

    test1 = SetNadconPath(r"C:\Program Files\CORPSCON6\Nadcon")
    test2 = SetVertconPath(r"C:\Program Files\CORPSCON6\Vertcon")
    test3 = SetGeoidPath(r"C:\Program Files\CORPSCON6\Geoid")

    ###################################
    ##
    ## Set Geographic or Stateplane
    ##
    ##################################
    sysInNum = 2 
    insys = SetInSystem(sysInNum)
    outsys = SetOutSystem(sysOutNum)

    ###################################
    ##
    ## Set Datum 83 or 27
    ##
    ##################################
    datumInYear = 1983
    indat = SetInDatum(datumInYear)
    datumOutYear = outdatyear
    outdat = SetOutDatum(datumOutYear)

    ###################################
    ##
    ## Set Zone ie 4202
    ##
    ##################################

    incode = 4202
    inzone = SetInZone(incode)

    outcode = outzonecode
    outzone = SetOutZone(outcode)

    ###################################
    ##
    ## Set Units
    ##
    ##################################

    units = 1

    outunits = SetOutUnits(units)
    inunits = SetInUnits(units)


    ###################################
    ##
    ## Set V Datum
    ##
    ##################################

    invdatum = SetInVDatum(1988)
    outvdatum = SetOutVDatum(1988)


    ###################################
    ##
    ## Set V Units
    ##
    ##################################

    invunits = SetInVUnits(1)
    outvunits = SetOutVUnits(1)

    geoidbase = SetGeoidCodeBase(2003)

    intcorpse = corpslib.corpscon_initialize_convert()

    #inX = 2790955
    #inY = 503380 
    #inZ = 2800.00

    xin = c_double(inX)
    yin = c_double(inY)
    zin = c_double(inZ)

    xout = c_double()
    yout = c_double()
    zout = c_double()

    SetXIn(xin)
    SetYIn(yin)
    SetZIn(zin)

    corpslib.corpscon_convert()

    corpslib.GetXOut.restype = c_double
    corpslib.GetYOut.restype = c_double
    corpslib.GetZOut.restype = c_double

    pntX = corpslib.GetXOut()
    pntY = corpslib.GetYOut()
    pntZ =  corpslib.GetZOut()



    return pntX,pntY,pntZ

x,y,z = conCoords(2,1983,4202,2790955,503380,2800.00)
print(x,y,z)

可以在这里找到corpscon dll。

Corpscon.dll

1 个答案:

答案 0 :(得分:1)

您可以使用pywin32使用32位Python创建COM服务器,然后在64位Python中使用COM对象。

这是我写的一个中文拼音转换器。它需要像wo3 shi4 mei3guo2ren2这样的编号输入并将其转换为wǒ shì měiguórén

_UMLAUT_U = u'\N{LATIN SMALL LETTER U WITH DIAERESIS}'

# tone number to combining diacritical table. 
_TONE = {u'1':u'\N{COMBINING MACRON}',
        u'2':u'\N{COMBINING ACUTE ACCENT}',
        u'3':u'\N{COMBINING CARON}',
        u'4':u'\N{COMBINING GRAVE ACCENT}',
        u'5':u''}

class Pinyin:
    _public_methods_ = ['Convert']
    _reg_progid_ = 'PythonUtil.Pinyin'
    _reg_clsid_ = '{3A7A52BA-3162-4fc1-8182-869258D2754D}'

    @staticmethod
    def _convert(matchobj):
        """_convert(matchobj) -> replacement text
        Helper function for re.sub with three groups.
        Group 1 - one or more vowels
        Group 2 - zero or more consonants
        Group 3 - tone character '1'-'5'
        Applies pinyin tone marks to the appropriate vowel.
        Algorithm:
        In vowels, replace 'v' with umlaut-u.
        First 'a' or 'e' in vowels gets the mark,
        else first 'ou', 'o' gets the mark,
        else last vowel gets the mark.
        """
        import unicodedata
        vowels,consonants,tone = matchobj.groups()
        vowels = vowels.replace(u'v',_UMLAUT_U)
        n = vowels.lower().find(u'a')
        if n == -1:
            n = vowels.lower().find(u'e')
        if n == -1:
            n = vowels.lower().find(u'ou')
        if n != -1:
            # a, e, or ou found.
            # Add accent after the a, e, or o
            retval = vowels[:n+1] + _TONE[tone] + vowels[n+1:] + consonants
        else:
            # accent after the last vowel
            retval = vowels + _TONE[tone] + consonants
        return unicodedata.normalize('NFC',retval)

    def Convert(self,pinyin_with_tone_numbers):
        """Convert(self,pinyin_with_tone_numbers) -> pinyin_with_tone_marks
        Given a pinyin string with tone numbers, return a converted unicode
        string with tone marks.  Requires 'v' to represent umlaut-u.
        """
        import re
        # Calls conversion function for each match.
        return re.sub(
            u'''(?ix)       # ignore case, verbose
            ([aeiouv]+)     # one or more vowels (v for umlaut-u)
            ([^aeiouv]*)    # zero or more non-vowels
            ([12345])       # tone mark 1-5
            ''',self._convert,pinyin_with_tone_numbers)

if __name__ == '__main__':
    import win32com.server.register
    win32com.server.register.UseCommandLine(Pinyin)

运行以下脚本以使用32位Python来注册COM服务器,然后在64位Python中使用:

>>> import win32com.client
>>> s=win32com.client.Dispatch('PythonUtil.Pinyin')
>>> s.Convert('wo3 shi4 mei3guo2ren2')
'wǒ shì měiguórén'

根据需要适应您的应用程序。