teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

エイリアスを用意する

2018/05/05 00:55

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  なお、Cの関数(C++内なら`export "C"`された関数)はそのままの名前でDLLに登録されるため、上記のような問題は起きません。そのため、VC++側でCの関数で出来たラッパーを作るという手段もありますが、簡単にできるような方法は見つけられませんでした。
16
16
 
17
+ 名前だけの問題であれば、エイリアスを用意することで無理矢理使用することは出来ます(実際の例は後述)。ただし、名前が異なるだけではなく、内部の構造もコンパイル依存の所が存在するため、必ずうまくいくとは限りません。手動でエイリアスを用意するなどの苦労するばかりか、うまくいかなくて徒労に終わる可能性が高いため、推奨は出来ません。
18
+
17
19
  ---
18
20
 
19
21
  ついでに、この質問を読んで疑問に思った方への補足です。これまでの質問にあった皆さんの優れた回答を読んでいなかった人達もいるかと思いますので、参考にしてください。
@@ -23,4 +25,100 @@
23
25
  * OpenCVはCmakeを使うことを前提に設計されています。OpenCVをコンパイルする場合はCmakeを用いて依存関係を解決したMakefileやVisual Studioのプロジェクトファイルを作る必要があります。OpenCVを使うプログラムを作る場合も、Cmakeで依存関係を解決できるようにCmakeのファイルが用意されています。
24
26
  * OpenCVの公式バイナリや上記のMSYS2パッケージはCUDAが有効になっていません。CUDAを使用したい場合は自分でコンパイルする必要があります。
25
27
  * OpenCV 3からCのAPIは非推奨になり、C++のAPIを使うことが推奨されています。しかし、CのAPIを使用できないわけではありません。
26
- * Cmakeは依存関係等を解決してMakefileやVisual Studioのプロジェクトファイルを作成するツールです。往年のautomakeに取って代わるツールですが、UNIX/Linux環境のみならず、WindowsでのVisual Studioにも対応しているなど、マルチプラットフォームなC/C++プログラムで特に使われるようになっているツールです。
28
+ * Cmakeは依存関係等を解決してMakefileやVisual Studioのプロジェクトファイルを作成するツールです。往年のautomakeに取って代わるツールですが、UNIX/Linux環境のみならず、WindowsでのVisual Studioにも対応しているなど、マルチプラットフォームなC/C++プログラムで特に使われるようになっているツールです。
29
+
30
+ ---
31
+
32
+ ### OpenCVの公式バイナリをMinGW GCCから無理矢理使う方法
33
+
34
+ MSYS2+MINGW64環境で実施します。GCCおよびdlltool等はインストール済みとします。また、VS2017のランタイムもインストール済みとします。特に明記しませんが、Windows 10の64bit環境です。`$`はシェルのプロンプトになります。
35
+
36
+ 1, 作業フォルダーにソースコード"sample.c"を置き、次のように書き換えます。(画像のファイル名を設定し、不要なヘッダを削除しただけです)
37
+
38
+ sample.c
39
+ ```C
40
+ #include <opencv2/opencv.hpp>
41
+
42
+ int main(void)
43
+ {
44
+ cv::Mat src_img;
45
+ src_img = cv::imread("sample.jpg", 1);
46
+ // 画像が読み込まれなかったらプログラム終了
47
+ if (src_img.empty()) return -1;
48
+
49
+ // 結果画像表示
50
+ cv::namedWindow("Image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
51
+ cv::imshow("Image", src_img);
52
+ cv::waitKey(0);
53
+ }
54
+ ```
55
+
56
+ 2, 適当なJPEGファイルを作業フォルダーにおいて、"sample.jpg"という名前にします。
57
+
58
+ 3, OpenCVのWindows版公式バイナリopencv-3.4.1-vc14_vc15.exeを実行し、Cドライブ直下にインストールします。"C:\opencv\build\x64\vc15\bin\opencv_world341.dll"を作業フォルダーにコピーします。
59
+
60
+ ```
61
+ $ cp /c/opencv/build/x64/vc15/bin/opencv_world341.dll .
62
+ ```
63
+
64
+ 4, 下記内容のDEFファイル"opencv_world341_gcc.def"を作成します。
65
+
66
+ opencv_world341_gcc.def
67
+ ```DEF
68
+ LIBRARY "opencv_world341.dll"
69
+ EXPORTS
70
+ ; cv::String::allocate(unsigned long long)
71
+ ?allocate@String@cv@@AEAAPEAD_K@Z
72
+ _ZN2cv6String8allocateEy==?allocate@String@cv@@AEAAPEAD_K@Z
73
+ ; cv::Mat::deallocate()
74
+ ?deallocate@Mat@cv@@QEAAXXZ
75
+ _ZN2cv3Mat10deallocateEv==?deallocate@Mat@cv@@QEAAXXZ
76
+ ; cv::fastFree(void*)
77
+ ?fastFree@cv@@YAXPEAX@Z
78
+ _ZN2cv8fastFreeEPv==?fastFree@cv@@YAXPEAX@Z
79
+ ; cv::imread(cv::String const&, int)
80
+ ?imread@cv@@YA?AVMat@1@AEBVString@1@H@Z
81
+ _ZN2cv6imreadERKNS_6StringEi==?imread@cv@@YA?AVMat@1@AEBVString@1@H@Z
82
+ ; cv::String::deallocate()
83
+ ?deallocate@String@cv@@AEAAXXZ
84
+ _ZN2cv6String10deallocateEv==?deallocate@String@cv@@AEAAXXZ
85
+ ; cv::namedWindow(cv::String const&, int)
86
+ ?namedWindow@cv@@YAXAEBVString@1@H@Z
87
+ _ZN2cv11namedWindowERKNS_6StringEi==?namedWindow@cv@@YAXAEBVString@1@H@Z
88
+ ; cv::imshow(cv::String const&, cv::_InputArray const&)
89
+ ?imshow@cv@@YAXAEBVString@1@AEBV_InputArray@1@@Z
90
+ _ZN2cv6imshowERKNS_6StringERKNS_11_InputArrayE==?imshow@cv@@YAXAEBVString@1@AEBV_InputArray@1@@Z
91
+ ; cv::waitKey(int)
92
+ ?waitKey@cv@@YAHH@Z
93
+ _ZN2cv7waitKeyEi==?waitKey@cv@@YAHH@Z
94
+ ```
95
+
96
+ 5, 下記コマンドを実行し、libopencv_world341.aを作成します。
97
+
98
+ ```
99
+ $ dlltool -D opencv_world341.dll -d opencv_world341_gcc.def -l libopencv_world341_gcc.a
100
+ ```
101
+
102
+ 6, 作成したライブラリにリンクしてコンパイルします。
103
+
104
+ ```
105
+ $ g++ -O2 -Wall -std=c++17 -I/c/opencv/build/include -L. sample.cpp -lopencv_world341_gcc -o sample.exe
106
+ ```
107
+
108
+ 7, MSYS2環境でsample.exeを実行できるか確認します。
109
+
110
+ ```
111
+ $ ./sample.exe
112
+ ```
113
+
114
+ 8, エクスプローラー上でも実行できるように依存関係のDLLをコピーしておきます。
115
+
116
+ ```
117
+ $ cp /mingw64/bin/libgcc_s_seh-1.dll .
118
+ $ cp /mingw64/bin/libstdc++-6.dll .
119
+ $ cp /mingw64/bin/libwinpthread-1.dll .
120
+ ```
121
+
122
+ 9, エクスプローラー上でsample.exeをダブルクリックすると画像が表示されます。
123
+
124
+ これで完了です。お疲れ様でした。シンボル名を調べるのは二度とやりたくないです。なお、この方法は必ずうまくいくとは限らず、今回はたまたまうまくいっただけに過ぎません。私もよくわかっていない(特にDEFファイルが未だによくわからない)ため、解説はありません。

1

OpenCVを使った。

2018/05/05 00:54

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -19,7 +19,7 @@
19
19
  ついでに、この質問を読んで疑問に思った方への補足です。これまでの質問にあった皆さんの優れた回答を読んでいなかった人達もいるかと思いますので、参考にしてください。
20
20
 
21
21
  * OpenCV 3.4.1の公式バイナリのWindows版はVisual Studio 2015とVisual Studio 2017のVC++用にコンパイルされています。DLLおよびLIBはその二つから使えるようになっていますが、MinGW GCC等のVisual Studio以外のコンパイラから使用できるようにはなっていません(理由は上で述べたとおりです)。MinGW GCC用のバイナリは公式にはありません。
22
- * MSYS2にはOpenCVのバイナリパッケージ(mingw-w64-x86_64-opencvとmingw-w64-i686-opencv)が存在します。そちらを使えばMSYS2環境でのMinGW GCCでOpenCVをコンパイルすることは可能です。OpenCV自体をMSYS2上でコンパイルするためのパッチおよび手順もMSYS2のレポジトリに公開されています。
22
+ * MSYS2にはOpenCVのバイナリパッケージ(mingw-w64-x86_64-opencvとmingw-w64-i686-opencv)が存在します。そちらを使えばMSYS2環境でのMinGW GCCでOpenCVを使ったプログラムをコンパイルすることは可能です。OpenCV自体をMSYS2上でコンパイルするためのパッチおよび手順もMSYS2のレポジトリに公開されています。
23
23
  * OpenCVはCmakeを使うことを前提に設計されています。OpenCVをコンパイルする場合はCmakeを用いて依存関係を解決したMakefileやVisual Studioのプロジェクトファイルを作る必要があります。OpenCVを使うプログラムを作る場合も、Cmakeで依存関係を解決できるようにCmakeのファイルが用意されています。
24
24
  * OpenCVの公式バイナリや上記のMSYS2パッケージはCUDAが有効になっていません。CUDAを使用したい場合は自分でコンパイルする必要があります。
25
25
  * OpenCV 3からCのAPIは非推奨になり、C++のAPIを使うことが推奨されています。しかし、CのAPIを使用できないわけではありません。