第36講 複数のソフトをナビゲーションソフトから起動する(マルチスレッド研究)☆☆
第8話 
数独探索ソフトを実装する

第8話と第9話では、第7話と同様にコピペを使い数独探索ソフトと魔方陣ソフトを実装していきます。
数独探索ソフトは参考ヘッダファイルForm11.hを使います。
魔方陣探索ソフトは、
第29講 細胞構成法による魔方陣作成の普遍化△第12話 普遍完成版

のダウンロード用参考ファイルForm1.hをコピペします。

まず、数独探索ソフトの実装からです。
第8話と同様にまず、Form11.hをクリックします。
そして、ドラッグなどの方法(一番よい方法は、一番上の行の左側でクリックして、次に七番下の行の左側でクリックする方法)で、
一番上の行から一番下の行までで範囲指定をします。
そして、右クリック→コピー(お勧めは、Ctrl+Cの方法)をします。
VC++のForm3.h[デザイン]とクリックして、Form3を表示させ、Form3の真ん中あたりで右クリック→コードの表示を選び、
Form3.hのコードを表示します。
そして、ドラッグなどの方法で一番上の行から一番下の行まで範囲をして、
右クリック→貼り付け(Ctrl+Vがお勧め)をします。
すると、Form3.hのコードがForm11.hのコードに入れ替わります。

次に、その入れ替わったコードの上から7行目の
namespace 9次数独作成4スレッド(BackgrouンdWorker版) {
9次数独作成4スレッド(BackgrouンdWorker版)の部分を、プロジェクトを立ち上げたときの名前に変更します。
私の場合は、『スレッドの起動』ですのでそれに変更します。
実は手で入力してよいのですが、
Form1.hの3行目あたりの
namespace スレッドの起動 {
をコピペでいただいた方がミスが少ないと思います。
次に、メニューの編集→クイック置換を利用して、Form1をまとめて(ドキュメントごと)Form3に変更します。
すると、『16個のアイテムを変更しました』と表示されるはずです。

さらに、次の操作はお分かりですね。
そうです。
上から3行目から6行目までの
int n;
int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
int x[100],y[100];
int s1,s2,s3,s4;
をすべてstatic変数に変更して、
static int n;
static int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
static int x[100],y[100];
static int s1,s2,s3,s4;
とします。

同じマルチスレッドでも素数探索ソフトは、以上の操作でビルドに成功しソフトが正常に動きましたが、
baskgroundWoker使っている場合は、もう一カ所変更が必要です。
static int n;
static int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
static int x[100],y[100];
static int s1,s2,s3,s4;

の位置を
#pragma once
#include<stdlib.h>
static int n;
static int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
static int x[100],y[100];
static int s1,s2,s3,s4;

namespace スレッドの起動 {
  
using namespace System;
  using namespace System::ComponentModel;

  using namespace System::Collections;
  using namespace System::Windows::Forms;
  using namespace System::Data;
  using namespace System::Drawing;
            ・
            ・
            ・
冒頭の位置から
#pragma once
#include<stdlib.h>
namespace スレッドの起動 {
  static int n;
  static int a1[10][10],a2[10][10],a3[10][10],a4[10][10],as1[100][10][10],as2[100][10][10],as3[100][10][10],as4[100][10][10];
  static int x[100],y[100];
  static int s1,s2,s3,s4;

  
using namespace System;
  using namespace System::ComponentModel;
  using namespace System::Collections;

  using namespace System::Windows::Forms;
  using namespace System::Data;
  using namespace System::Drawing;
            ・
            ・
            ・
に移動しなければならないのです。

どうしてでしょうか。
私は、グロール変数はnamespaceの前に記述しなければならないと思っていましたが、
これは私の勘違いで、基本的には冒頭に記述しても、
namespaceの中に記述しても問題なかったようです。
今までのソフト(例えば、数独問題解決ソフトVer.7や数独作成ソフト)のグローバル変数の位置をnamespaceの中に記述し直しても、
実験した範囲では、すべて動きました。
ですから、基本的にはグローバル変数の宣言はnamespaceの前で行っても、namespaceの中で行っても、
どちらでもよいということになりそうです。
ところば、素数探索ソフトの原本の方は

#pragma once
#include <math.h>
#include<stdlib.h>
#include<set>
using namespace std;
namespace 素数探索4スレッド {
  int N;
  int cn1,cn2,cn3,cn4;
  int s1[25000000],s2[25000000],s3[25000000],s4[25000000];
  using namespace System;
  using namespace System::ComponentModel;
  using namespace System::Collections;
  using namespace System::Windows::Forms;
  using namespace System::Data;
  using namespace System::Drawing;
  using namespace System::Threading;
            ・
            ・
            ・
現在の『スレッドの起動』の場合は、
これでは動かず
#pragma once
#include <math.h>
#include<stdlib.h>
#include<set>
using namespace std;
int s1[25000000],s2[25000000],s3[25000000],s4[25000000];
namespace 素数探索4スレッド {
  int N;
  int cn1,cn2,cn3,cn4;
  using namespace System;
  using namespace System::ComponentModel;
  using namespace System::Collections;
  using namespace System::Windows::Forms;
  using namespace System::Data;
  using namespace System::Drawing;
  using namespace System::Threading;
            ・
            ・
            ・
どういう訳か、int s1[25000000],s2[25000000],s3[25000000],s4[25000000];だけはnamespaceの前に置かないとエラーします。

謎はもう一つ残っています。
今までグローバル変数は、すべてnamespaceの前で宣言してもエラーしなかったのに、
baskgroundWokerの場合は冒頭においたのではなぜ失敗するのか・・・・

ごめんなさい。
?です。
申し訳ございませんが、グローバル変数はnamespaceの前か中のどちらも試して、
うまくいく方を採用する、という方策をとるというアバウトな話で許していただければと思います。
今回の2つの謎については、解明できたらアップしますのでお待ちいただければと思います。

第7話へ 第9話へ


戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)