【问题标题】:Can I call this 32bit dll in 64bit python using interprocess comunication?我可以使用进程间通信在 64 位 python 中调用这个 32 位 dll 吗?
【发布时间】:2019-08-20 08:19:25
【问题描述】:

我需要从 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

【问题讨论】:

  • 你想做的事很难。您必须编写一个 Python 模块,该模块 (1) 加载 DLL (2) 为其所有函数提供包装器,并且 (3) 响应来自另一个程序的请求(通过命名管道或 COM 或 http 或其他东西)以调用这些函数并返回结果。
  • 您无法在 64 位程序中直接使用 32 位 dll。所以你需要一些可以作为 32 位的东西并调用它,或者找到 64 位库...
  • 是的,这听起来很难。我想我会寻找另一种解决方案,感谢您为我节省了一些时间。
  • 该 DLL 的 64 位版本位于:dhawk.github.io/corpscon_v6_64bit.dll
  • 谢谢大卫,我很感激。这个周末我要去看看。

标签: python ctypes 32bit-64bit


【解决方案1】:

您可以使用pywin32 使用 Python 32 位创建 COM 服务器,然后在 Python 64 位中使用 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)

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

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

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

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 2012-06-18
    • 2012-01-29
    • 2010-09-18
    • 2016-06-04
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    相关资源
    最近更新 更多