質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

940閲覧

CythonでC++のkeybd_eventが使えない(LinkError等が発生)

PossiblyApple

総合スコア17

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/22 05:06

編集2018/09/22 05:13

前提・実現したいこと

Python3にて、C++のkeybd_event関数を高速に使おうとしています。
そこでCythonを用いて、keybd_eventを使おうといろいろ試しているのですがうまくいきません。

(keybd_eventを使うだけならpyautoguiで事足りますが、1度のキー出力に0.1秒ほどかかってしまいます。
コードをさらに高速化させたいため、Cythonを使おうとしています)

発生している問題・エラーメッセージ

(key.pyxおよびsetup.pyは下に載っています)
key.pyxを実行すると、以下のようなエラーが出ます。

Traceback (most recent call last): File "<ipython-input-1-414ff3ef1721>", line 1, in <module> runfile('D:/(ユーザ名)/proglam/Pythpn/cython/key.pyx', wdir='D:/(ユーザ名)/proglam/Pythpn/cython') File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 666, in runfile ipython_shell.run_cell_magic('cython', '', f.read()) File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2167, in run_cell_magic result = fn(magic_arg_s, cell) File "<decorator-gen-130>", line 2, in cython File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\IPython\core\magic.py", line 187, in <lambda> call = lambda f, *a, **k: f(*a, **k) File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\Cython\Build\IpythonMagic.py", line 329, in cython quiet=args.quiet) File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\Cython\Build\IpythonMagic.py", line 439, in _build_extension build_extension.run() File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\command\build_ext.py", line 339, in run self.build_extensions() File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\command\build_ext.py", line 448, in build_extensions self._build_extensions_serial() File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\command\build_ext.py", line 473, in _build_extensions_serial self.build_extension(ext) File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\command\build_ext.py", line 558, in build_extension target_lang=language) File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\ccompiler.py", line 717, in link_shared_object extra_preargs, extra_postargs, build_temp, target_lang) File "C:\Users\(ユーザ名)\Anaconda3\lib\distutils\_msvccompiler.py", line 481, in link raise LinkError(msg) LinkError: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe' failed with exit status 1120

また、コマンドプロンプト上で python setup.py build_ext --inplace と入力して、
setup.pyをビルドしようとすると、以下のようなエラーが出ます。

running build_ext cythoning key.pyx to key.c building 'key' extension C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c / nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\(ユーザ名)\Anaconda3\include -IC:\Users\mas a\Anaconda3\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\IN CLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC :\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86) \Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include \winrt" /Tckey.c /Fobuild\temp.win-amd64-3.5\Release\key.obj key.c C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe /n ologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C :\Users\(ユーザ名)\Anaconda3\libs /LIBPATH:C:\Users\(ユーザ名)\Anaconda3\PCbuild\amd64 "/LIB PATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPATH :C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64" "/LIBPATH:C:\ Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64" /EXPORT:PyInit_key buil d\temp.win-amd64-3.5\Release\key.obj /OUT:D:\(ユーザ名)\proglam\Pythpn\cython\key. cp35-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.5\Release\key.cp35-win_amd64.l ib key.obj : warning LNK4197: export 'PyInit_key' specified multiple times; using f irst specification Creating library build\temp.win-amd64-3.5\Release\key.cp35-win_amd64.lib and object build\temp.win-amd64-3.5\Release\key.cp35-win_amd64.exp key.obj : error LNK2001: unresolved external symbol __imp_keybd_event D:\(ユーザ名)\proglam\Pythpn\cython\key.cp35-win_amd64.pyd : fatal error LNK1120: 1 unresolved externals error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\ x86_amd64\link.exe' failed with exit status 1120

該当のソースコード

key.pyxとsetup.pyが同一のフォルダに入っています。
key.pyx

Python3

1cdef extern from "windows.h": 2 void keybd_event(int a,int b,int c,int d) 3 4def f(a,b,c,d): 5 keybd_event(a,b,c,d) 6 return a

setup.py(Cythonドキュメントを参考にしました)

Python3

1from distutils.core import setup 2from distutils.extension import Extension 3from Cython.Distutils import build_ext 4 5ext_modules = [Extension("key", ["key.pyx"])] 6 7setup( 8 name = 'key world app', 9 cmdclass = {'build_ext': build_ext}, 10 ext_modules = ext_modules 11)

試したこと

① key.pyxの内容を以下のように変える。

Python3

1cdef extern from "windows.h": 2 void keybd_event(int a,int b,int c,int d) 3 4cdef int f(int a,int b,int c,int d): 5 keybd_event(a,b,c,d) 6 return a

これにより、上記のエラーはどちらも起こらなくなり、後者のコマンドでは正常に
key.cp35-win_amd64.pyd
が出力されました。

そうして、import keyでkeyをインポートすることはできたのですが、
関数fを使おうとすると、以下のように「関数fが定義されていない」とエラーが出て使えませんでした。
AttributeError: module 'key' has no attribute 'f'


② key.pyxの内容を以下のように変える。
(①の2つ目のcdefcpdefに変えただけです)

Python3

1cdef extern from "windows.h": 2 void keybd_event(int a,int b,int c,int d) 3 4cpdef int f(int a,int b,int c,int d): 5 keybd_event(a,b,c,d) 6 return a

しかし、これを行っても、最初と同じようなエラーが出てしまい解決できませんでした。
1つ目のエラーは同じですが、2つ目のエラーは少し変化がありました。

running

1cythoning key.pyx to key.c 2building 'key' extension 3C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c 4nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\(ユーザ名)\Anaconda3\include -IC:\Users\ma 5a\Anaconda3\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\I 6CLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-I 7:\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86 8\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\includ 9\winrt" /Tckey.c /Fobuild\temp.win-amd64-3.5\Release\key.obj 10key.c 11C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe / 12ologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH: 13:\Users\(ユーザ名)\Anaconda3\libs /LIBPATH:C:\Users\(ユーザ名)\Anaconda3\PCbuild\amd64 "/LI 14PATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPAT 15:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64" "/LIBPATH:C: 16Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64" /EXPORT:PyInit_key bui 17d\temp.win-amd64-3.5\Release\key.obj /OUT:D:\(ユーザ名)\proglam\Pythpn\cython\key 18cp35-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.5\Release\key.cp35-win_amd64. 19ib 20key.obj : warning LNK4197: export 'PyInit_key' specified multiple times; using 21irst specification 22 Creating library build\temp.win-amd64-3.5\Release\key.cp35-win_amd64.lib and 23object build\temp.win-amd64-3.5\Release\key.cp35-win_amd64.exp 24key.obj : error LNK2001: unresolved external symbol __imp_keybd_event 25D:\(ユーザ名)\proglam\Pythpn\cython\key.cp35-win_amd64.pyd : fatal error LNK1120: 261 unresolved externals 27error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\ 28x86_amd64\link.exe' failed with exit status 1120

③ そもそもCythonやCモジュールの導入に失敗しているのではないかと思い、
別のコードを入力してみて、正常に動くか確かめてみました。

sin.pyx

Python3

1cdef extern from "math.h": 2 double sin(double) 3 4def f(x): 5 return sin(x)

setup2.py

Python3

1from distutils.core import setup 2from distutils.extension import Extension 3from Cython.Distutils import build_ext 4 5ext_modules = [Extension("sin", ["sin.pyx"])] 6 7setup( 8 name = 'sin world app', 9 cmdclass = {'build_ext': build_ext}, 10 ext_modules = ext_modules 11)

結果、sin.pyxは正常に実行できました。
また、python setup.py build_ext --inplaceを入力してこれをビルドすることもできました。
そして、正常に関数fを使うこともできました。

よって、Cythonやmath.hに問題はないとみられます。


④ C:\Program Files (x86)\Microsoft Visual Studio 14.0 内には、windows.hが入っていません。
windows.hは、C:\Program Files (x86)\Windows Kits\8.1\Include\umの中に入っていました。

そこで、Microsoft Visual Studio 14.0のフォルダ内の
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include中にWindows.hを入れて、
問題のコードと②のコードをそれぞれ実行してみましたが、変化がなく、これまでと同じように
エラーが発生しました。

(ちなみに、Windows.hは単体では動きませんが、エラーメッセージに変化がなかったことから、
結局この方法には効果がなかったと考えています)


私が試したのはここまでですが、どれも解決に至りませんでした。
C++コンパイラの再インストールなどをする、という手もありますが、
環境の再整備が大変そうなのでやっていません。

補足情報(FW/ツールのバージョンなど)

使用したものは以下の通りです。

  • OS

Windows8.1 (64-bit)

  • プログラム等

Anaconda3 5.2.0 (64-bit)
Python 3.5.6
Cython 0.28.5
Spyder 3.3.1 (使用エディタ)

  • C++コンパイラ

Microsoft Visual Studio 14.0 (x86)
Microsoft Visual C++ 2017 Redistributable (x64) - 14.15.26706
(Cython内で使われているのはVisual Studioの方です)

状況の説明は以上です。
長文になってしまい、すみません。
何か分かることがあれば、ぜひご教授ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました

この質問をしたあとから今まで、2か月余り回答がありませんでした。
また、自分でこれをさらに調べてみたところ、以下のことがわかりました。

  • Cythonでkeybd_event(Windows.h)を使う方法はよくわからなかった

少なくとも私にはできません。というか、Cython等は計算を高速化するもので、こういうモジュール?を使うには向いていないのかな……?

  • そもそも、C++のkeybd_event自体が遅い

C++でも、1回のキーイベントに0.1秒くらいかかってしまうので、Cythonを使ってもあまり効果が出なさそうです。

ということで、解決になっていないかもしれませんが、
軽量化をしない(素直にPython内のpyautoguiを使う)」ということにしました。

###2019/3/18 追記

Python

1ctypes.windll.user32.keybd_event 2```を使ったところ1000倍速くなりました

投稿2018/11/09 10:48

編集2019/03/18 11:13
PossiblyApple

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問