V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
iMath
V2EX  ›  Python

悬赏至少 50 元,求帮忙 C++调用 dll 的方式转成 Python

  •  
  •   iMath · 2018-07-25 17:50:53 +08:00 · 7357 次点击
    这是一个创建于 2073 天前的主题,其中的信息可能已经有所发展或是发生改变。
    主要是想通过 Python 使用 WCaptureX.dll 里面的函数,涉及到的 dll 可以到这个软件的安装目录获取
    https://wordweb.info/free/
    这里提供了 C++调用 dll 的方法
    https://sites.google.com/a/deskperience.com/wordcapturexdoc/deployment/using-native-dlls---no-com
    另外的一些相关文档
    函数文档 https://sites.google.com/a/deskperience.com/wordcapturexdoc/wcapturex/wcapturex-interface/capture-method
    例子 https://sites.google.com/a/deskperience.com/wordcapturexdoc/wcapturex/wcapturex-interface/capture-method/visual-c

    是否有高手愿意帮忙把这个方法转成 Python 的,指导下我如何使用?为了表示诚意,我愿意出至少 50 元,大家先别嫌少,如果确实能搞定,我愿意再加点,谢谢各位!

    我折腾出这种来,貌似也还是不知道怎么用
    from ctypes import *
    # help(cdll.WCaptureX.CreateCOMObject)
    print(cdll.WCaptureX.CreateCOMObject)
    第 1 条附言  ·  2018-07-25 19:59:01 +08:00
    关键是我也还是个学生,没开始工作赚钱,所以给不了太多,并没有贬低技术价值的意思。
    第 2 条附言  ·  2018-07-25 20:05:47 +08:00
    对于这种问题不给点 money 让人家白白帮我,我觉得也是不现实,但是学生党又拿不出多少来……
    第 3 条附言  ·  2018-07-26 09:33:31 +08:00
    谈钱伤感情,我错了,各位!
    70 条回复    2018-07-31 14:58:55 +08:00
    huclengyue
        1
    huclengyue  
       2018-07-25 18:06:03 +08:00 via Android   ❤️ 7
    50 太多了,从没做过这么大的项目。。怎么办。
    RoyLeong
        2
    RoyLeong  
       2018-07-25 18:06:40 +08:00   ❤️ 5
    我看成了 50w,抱歉,打扰了
    Antidictator
        3
    Antidictator  
       2018-07-25 18:08:40 +08:00   ❤️ 6
    如果是以技术讨论的形式询问不但不会让人反感,而且说请喝星巴克的话不仅成本会降低而且有更多人愿意帮忙。而不是给人这种你的工作量只值 50 块钱的感觉。
    FanWall
        4
    FanWall  
       2018-07-25 18:11:28 +08:00 via Android
    自行检索 python win32com
    keramist
        5
    keramist  
       2018-07-25 18:12:57 +08:00 via Android
    看来技术真的不值钱 所以你自己弄吧
    Eugene1024
        6
    Eugene1024  
       2018-07-25 18:20:53 +08:00
    技术看来真的不值钱了 +1
    ayyll
        7
    ayyll  
       2018-07-25 18:25:18 +08:00 via Android
    曾经有过 mfc 转成 py 的经历。。不难吧 你搜搜 复制粘贴巴拉巴拉就完了
    keysona
        8
    keysona  
       2018-07-25 18:28:25 +08:00
    不好意思,我膨胀了....
    beginor
        9
    beginor  
       2018-07-25 18:29:24 +08:00 via Android
    @RoyLeong 我以为就我一个看成 50 万 🤣
    FanWall
        10
    FanWall  
       2018-07-25 18:36:38 +08:00 via Android   ❤️ 5
    @FanWall #4

    因为这是**组件对象模型**而不是 DLL,调用的是接口,你应该也可以通过 win32api 实现,但既然用 Python 了,为简单计,依然推荐 win32com

    这有啥嘲讽的,这也算值钱的技术?建议楼主去网上找点开发互助群加一加,问基础问题这类群里比较友好,v2ex 适合分手了来问情感问题。
    Beebird
        11
    Beebird  
       2018-07-25 18:41:45 +08:00
    哈哈,看评论乐了。不过我正好有个例子不知道楼主用不用得上 @iMath https://gist.github.com/beebird/9c37adf19a8436ccdd264a9beb09a8d1
    realpg
        12
    realpg  
       2018-07-25 19:53:51 +08:00
    50 太多了,怕干不好当不起啊
    iMath
        13
    iMath  
    OP
       2018-07-25 20:01:59 +08:00
    @Antidictator 对于这种问题不给点 money 让人家白白帮我,我觉得也是不现实,但是学生党又拿不出多少来……
    iMath
        14
    iMath  
    OP
       2018-07-25 20:05:17 +08:00
    @FanWall @ayyll
    谢谢指教!
    我主要是看不懂那些 C++代码,所以就是用上 pywin32 也无从下手,更别提调用这个 dll 里面的函数了。能否 show some code ?谢谢
    yangguoshuai
        15
    yangguoshuai  
       2018-07-25 20:06:58 +08:00 via Android
    @iMath 楼主很隐晦的说大家 talk is cheap。。
    iMath
        16
    iMath  
    OP
       2018-07-25 20:07:13 +08:00
    @Beebird 谢谢!
    和你的代码类似的例子之前我也看过几个,但我主要是看不懂那些 C++代码,所以也就无从下手了
    ftdejo
        17
    ftdejo  
       2018-07-25 20:12:12 +08:00
    https://stackoverflow.com/questions/252417/how-can-i-use-a-dll-file-from-python
    善用谷歌和 Stack Overflow,说实话你这个 50 块是在侮辱你自己的信息获取能力··
    FanWall
        18
    FanWall  
       2018-07-25 20:13:48 +08:00 via Android
    @iMath #14

    手头只有爪机,你就只百度 Python win32com 就有例子了

    https://www.cnblogs.com/jasonli-01/articles/6612020.html

    为了更方便,可以先用 regsvr32 注册一下 DLL
    mritd
        19
    mritd  
       2018-07-25 20:23:18 +08:00 via iPhone   ❤️ 5
    你知道,这个帖子最大的败笔是什么么?

    如果只是纯技术请教就别谈钱,会的自然告诉你

    如果是外包项目就别扯太多技术,更别提整个 50 块钱的事

    你说会的人告诉你了,这 50 要还是不要?

    要: 打发要饭呢?
    不要: 有偿的操作,当外包干的,还得顶着心里压力,不要就亏了
    sagaxu
        20
    sagaxu  
       2018-07-25 20:35:21 +08:00 via Android
    50 还不够中饭点个外卖
    prolic
        21
    prolic  
       2018-07-25 20:41:04 +08:00 via Android   ❤️ 6
    要是标题没悬赏下面回复就是“课后作业自己做”,“知识付费”乱七八糟的了,合着 v2 一群外包接单的
    xuegj1010
        22
    xuegj1010  
       2018-07-25 20:53:15 +08:00
    技术无价,你这 50 块钱是在侮辱各位大佬。。。
    liuminghao233
        23
    liuminghao233  
       2018-07-25 21:12:52 +08:00 via iPhone
    我觉得搞计算机的
    花钱让别人帮忙写自己的 project
    是一种侮辱自己的行为
    yankebupt
        24
    yankebupt  
       2018-07-25 21:19:05 +08:00
    FanWell 正解...
    刚想说为啥那么多 wrapper 不用,看了一眼链接发现 COM 的...
    微软亲自挖坑咱也没啥可说的...
    17 楼那个 stackoverflow 最高票数 ctype 答案有可能不能用,但是楼层里 win32com 那个可能可以用...
    agee
        25
    agee  
       2018-07-25 21:20:13 +08:00 via iPhone
    貌似问题是没错,错在了提钱,还提个 50 块,哈哈
    iMath
        26
    iMath  
    OP
       2018-07-25 21:49:12 +08:00
    @FanWall @yankebupt 谢谢两位!
    我按文档里的注册了 dll
    https://sites.google.com/a/deskperience.com/wordcapturexdoc/wcapturex/register-wcapturex
    我的命令
    C:\Users\i>regsvr32 "C:\Program Files\WordWeb\WCaptureX.dll"
    然后我的代码
    from win32com.client import Dispatch
    zk = Dispatch("WCaptureX")
    估计也不对,出现如下异常
    Traceback (most recent call last):
    File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\client\dynamic.py", line 89, in _GetGoodDispatch
    IDispatch = pythoncom.connect(IDispatch)
    pywintypes.com_error: (-2147221005, '无效的类字符串', None, None)

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "D:\BaiduYunDownload\编程\Python\Win32COM.py", line 3, in <module>
    zk = Dispatch("WCaptureXLib")
    File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
    dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
    File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\client\dynamic.py", line 114, in _GetGoodDispatchAndUserName
    return (_GetGoodDispatch(IDispatch, clsctx), userName)
    File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\client\dynamic.py", line 91, in _GetGoodDispatch
    IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
    pywintypes.com_error: (-2147221005, '无效的类字符串', None, None)
    [Finished in 1.2s]
    ysc3839
        27
    ysc3839  
       2018-07-25 21:56:03 +08:00 via Android
    我可以免费帮你试试。
    要自己研究的话,找 C 语言调用 COM 的代码。
    个人理解 COM 接口本质是一个记录函数指针的 struct,取到函数指针后 call 就行了。
    iMath
        28
    iMath  
    OP
       2018-07-25 22:02:50 +08:00
    @ysc3839 多谢相助!在下对 win32 编程基本没什么认识,希望在你的指引下让我这小白上道~
    FanWall
        29
    FanWall  
       2018-07-25 22:07:37 +08:00 via Android
    @iMath #26

    名称参数大概写错了,可以借助你可以跑通的语言或者工具查看一下

    https://technet.microsoft.com/en-us/library/d0kh9f4c(fr-fr).aspx

    你也可以用 win32api 调用 CreateCOMObject,那就是 #27 的方案,第一次写麻烦点,不过对加深理解非常有帮助。
    ysc3839
        30
    ysc3839  
       2018-07-25 22:10:06 +08:00 via Android
    @iMath 另外能否提供一下示例代码?
    ysc3839
        32
    ysc3839  
       2018-07-25 22:41:25 +08:00 via Android
    @iMath 要直接运行就能使用的代码。
    iMath
        33
    iMath  
    OP
       2018-07-25 22:45:51 +08:00
    @ysc3839 谢谢!
    这里有各种语言的 demo
    https://github.com/yanivyhc/WordCaptureSamples
    iMath
        34
    iMath  
    OP
       2018-07-25 22:50:07 +08:00
    通过 oleview.exe 找到了这些内容,接下来怎么做也还要等摸索
    ![
    ]( )
    ysc3839
        35
    ysc3839  
       2018-07-25 23:51:49 +08:00
    @iMath
    IDispatch 是一个提供了动态特性的 COM 接口,可以实现不固定的函数。一般来说一些较高级的语言会封装这个接口,如 VB C# Delphi,#26 的代码也是使用这个接口。
    而 C/C++ 一般不会使用这个接口,因为在没有封装的情况下使用起来较为麻烦。
    ysc3839
        36
    ysc3839  
       2018-07-26 04:51:29 +08:00 via Android
    最终选用了 comtypes https://github.com/enthought/comtypes 这个模块。它同时支持一般的 COM 接口以及 IDispatch,且仅依赖内置的 ctypes 模块。
    Leigg
        37
    Leigg  
       2018-07-26 08:38:28 +08:00 via iPhone
    要么你别提钱。
    iMath
        38
    iMath  
    OP
       2018-07-26 09:06:33 +08:00
    @ysc3839 我误打误撞地似乎找到了可以用的方式,如下
    from win32com.client import Dispatch
    WCaptureX = Dispatch("{8F267988-0CA4-418C-8F94-B4BC5862B390}")
    print(WCaptureX.GetCursorInfo(None) )

    在我的电脑上,CLSID 是{8F267988-0CA4-418C-8F94-B4BC5862B390},不知道在别的机器上 CLSID 会不会变?
    ala2008
        39
    ala2008  
       2018-07-26 09:28:41 +08:00
    或者可以趁此学一下 c++?。。
    iMath
        40
    iMath  
    OP
       2018-07-26 09:32:32 +08:00
    谈钱伤感情,我错了,各位!
    realpg
        41
    realpg  
       2018-07-26 09:34:16 +08:00
    看过程,想起了当年被迫在 linux 下调用 dll 的折腾死人的一周
    ioth
        42
    ioth  
       2018-07-26 10:26:34 +08:00
    给你打个折,48 元。
    AEANWspPmj3FUhDc
        43
    AEANWspPmj3FUhDc  
       2018-07-26 10:38:56 +08:00
    "谈钱伤感情,我错了,各位!"

    这句话我要反驳一下。
    拜托,请问我们有什么感情?不和你谈钱,那谈什么?谈梦想?
    reus
        44
    reus  
       2018-07-26 10:57:00 +08:00
    钱不多,但有为知识付费的意识,这个难得
    FanWall
        45
    FanWall  
       2018-07-26 11:02:41 +08:00 via Android
    @iMath #38

    不会变,是常量,例如 Excel.* 也有对应的 CLSID,也可以互相转换。官方 SDK 里肯定也有定义的。
    iMath
        46
    iMath  
    OP
       2018-07-26 11:17:29 +08:00
    @reus 还是你理解我!理解万岁!
    iMath
        47
    iMath  
    OP
       2018-07-26 11:19:31 +08:00
    @FanWall 谢谢大哥不断的指教!
    我现在写出的代码如下
    from win32com.client import Dispatch
    import win32gui
    import mouse
    import time
    from threading import Timer

    WCaptureX = Dispatch("{8F267988-0CA4-418C-8F94-B4BC5862B390}")
    WInput = Dispatch("{4B484CCE-9120-49B7-A5F2-B8B183BFD808}")



    def onMouseClicked():
    # x,y=mouse.get_position()
    # windowHandle = win32gui.WindowFromPoint((x,y))
    # windowClassName= win32gui.GetClassName(windowHandle)
    # print(win32gui.GetClassName(windowHandle)) WInput.Hwnd=None
    windowHandle,x,y=WCaptureX.GetCursorInfo()
    WInput.Hwnd=windowHandle
    WInput.StartX=x
    WInput.StartY=y
    # WInput.EndX=x+100
    # WInput.EndY=y+100
    WResult=WCaptureX.Capture(WInput)
    print(WResult.TEXT ,WResult.Paragraph )


    mouse.on_click(onMouseClicked) # 实际是 released event
    mouse.wait(button='right', target_types=('double', ))


    我试了下 Word 2016 取词也是没问题,但是 Chrome 和 sumatraPDF 之类的软件就无法取词,估计是我没有找到正确的使用方式吧。
    据我所知,国内的欧路词典也是用这套工具,该软件在 Chrome 和 sumatraPDF 里取词没问题……
    @ysc3839
    lee88688
        48
    lee88688  
       2018-07-26 11:22:49 +08:00 via Android
    我之前用过内置的 ctypes 调用过 dll,感觉还挺好用的你可以去尝试一下
    FanWall
        49
    FanWall  
       2018-07-26 11:26:03 +08:00 via Android   ❤️ 1
    @iMath #47

    既然能跑通了那接下来的实现一般就是翻文档的事情了,加油吧
    Mmmmc
        50
    Mmmmc  
       2018-07-26 11:37:24 +08:00
    看得我五味杂陈
    iMath
        51
    iMath  
    OP
       2018-07-26 11:40:12 +08:00
    @lee88688 用 ctypes 我只能走到这一步就不知道下一步怎么走了
    from ctypes import *
    print(cdll.WCaptureX.CreateCOMObject)
    salamanderMH
        52
    salamanderMH  
       2018-07-26 11:42:57 +08:00
    其实吧,我觉得,钱不重要
    IbukiSuika
        53
    IbukiSuika  
       2018-07-26 11:43:24 +08:00
    楼主长个记性吧,以后这种别提钱就好了
    yyang179
        54
    yyang179  
       2018-07-26 12:04:40 +08:00 via Android
    ysc3839
        55
    ysc3839  
       2018-07-26 12:17:17 +08:00 via Android
    @iMath CLSID 是不会变的。如果你会的话那我就不写了。
    cszhiyue
        56
    cszhiyue  
       2018-07-26 12:37:06 +08:00
    “一般人们总认为要让别人做点事情,就应该给他们奖励,不管多少、 不论大小,有总比没有的好,但其实不然”

    “第一种方案纯粹依赖人们的内在动力,第二种则 与经济利益挂钩。那么这两种比较而言,哪种方式起到的效果更好呢? 第一种方案中,无偿献血是一种公益行为,人们愿意在这个时候做点贡 献,会自愿参加献血。而第二种方案因为有物质激励,人们自然而然地 会将献血看成一种经济行为。10 元的补助根本就是杯水车薪,数目实在 太小,起不到激励的作用,没有多少人会愿意为了拿到 10 元去卖血。所 以,没奖要比有小奖更能引导人们做好事,或者做我们希望他们做的事。 当然,如果献血给的钱特别多,比如一万元,那自然有很多人愿意去献 血,但我们比较的不是给一万元和不给钱,比如一万元,那自然有很多人愿意去献 血,但我们比较的不是给一万元和不给钱时人们献血的意愿,而是给 10 元和不给钱时人们献血的意愿。

    同样,当我还在耶鲁大学念书的时候,经常需要找一些学生帮我做 问卷。当时我还是一个穷学生,付不起多少钱。我发现如果我请别人帮 我做问卷然后给他们 1 美元的报酬,大多数人都不愿意帮我做。后来,我 索性就不给钱了,直接请他们帮我做问卷,这样反而有比较多的人愿意 帮忙。”


    摘录来自: 未知作者. “别做正常的傻瓜”。iBooks.
    iMath
        57
    iMath  
    OP
       2018-07-26 12:55:28 +08:00
    @cszhiyue 你的引用道出了我在这篇帖子里的处境,万分感谢!
    阁下能否推荐些你觉得大多数人都值得一看的书来看看?
    agostop
        58
    agostop  
       2018-07-26 13:05:09 +08:00
    其实是干技术的,都接受不了技术不值钱这个事实。
    forkon
        59
    forkon  
       2018-07-26 13:14:24 +08:00
    放了楼主的 50 元吧,他只是出于好意。
    Nostalgiaaaa
        60
    Nostalgiaaaa  
       2018-07-26 13:15:32 +08:00
    这个属于你把工作量化成 50 块钱了。。。一般做程序员的都不会觉得自己好几个小时就值 50,下次直接请教下方向就行了,剩下的自己摸索。
    jianpanxia
        61
    jianpanxia  
       2018-07-26 13:40:00 +08:00
    这...就值 50?
    tjxiter
        62
    tjxiter  
       2018-07-26 14:14:19 +08:00
    悬赏 和 50 元 放一起。 让大家开心了一把。

    楼主不是坏人。

    鉴定完毕。
    njlcazl
        63
    njlcazl  
       2018-07-26 14:37:35 +08:00
    为什么大家都把帖子标题里面的“至少”给忽略了
    mcone
        64
    mcone  
       2018-07-26 15:03:29 +08:00
    @njlcazl 好问题
    HR 发招聘启示的时候 工资都是范围 为什么大家一般只着重看范围的下限呢?
    zhuangzhuang1988
        65
    zhuangzhuang1988  
       2018-07-26 15:26:02 +08:00
    题主搞定没
    没搞定告诉你到哪里抄代码
    https://bitbucket.org/pyglet/pyglet/src/11fcff3d96d71619d55354bea6a9adc07efc8afc/pyglet/com.py?at=default
    pyglet 项目,纯 Python 做 opengl 外部 0 依赖
    涉及到 windows 上的一些肯定的 ctypes 上
    djxf
        66
    djxf  
       2018-07-26 20:46:42 +08:00 via Android
    50 元的讨论。
    iMath
        67
    iMath  
    OP
       2018-07-26 21:39:37 +08:00
    @zhuangzhuang1988 搞定了一部分,见 47 楼
    做这种事情,包括你说的那个项目,感觉都还是要懂些 C 或 C++才能入手,不然的话步履维艰啊
    lee88688
        68
    lee88688  
       2018-07-26 22:58:14 +08:00 via Android
    @iMath ctypes 调用 dll 函数就像是普通 python 函数调用一样,但是参数必须用 ctypes 中基本数据类型进行包裹,我记得官方网站上有相关教程还比较详细的
    iMath
        69
    iMath  
    OP
       2018-07-27 09:29:46 +08:00
    @lee88688 3Q !但是在我现在这个应用场景下用 ctypes 调用 dll 函数似乎难度又上了一个层次,我只能写出这种来就进行不下去了
    from ctypes import *
    print(cdll.WCaptureX.CreateCOMObject)
    lee88688
        70
    lee88688  
       2018-07-31 14:58:55 +08:00 via Android
    @iMath 难度不高,先通过 ctypes 导入 dll 然后准备好参数,通过 ctypes 调用并得到结果,这个流程并没有什么难度,可能只是你不熟悉库,直接百度 google 搜索一些基本教程很快就能上手。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3898 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 10:31 · PVG 18:31 · LAX 03:31 · JFK 06:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.