C++で作ったフォームをC#フォームから呼び出したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
hyumi478

C++で作ったフォームをC#フォームから呼び出したい

#1

投稿記事 by hyumi478 » 8年前

本掲示板への初めての投稿になります。宜しくお願い致します。
C++に関しては触れて間もない初心者です。

■開発環境・言語
Visual Studio Community 2015, C#, C++,
Windows7 Ultimate x64

■概要
C#.NETによるWindowsフォームアプリケーションが既にあり、その中の機能の一部として、DirectXライブラリによってC++言語に基づき描画されるフォームを表示したいと考えていますが、その方法がわかりません。

■ここまでに完了している作業
① 呼び出したいC++フォーム単体の作成(プロジェクト名:CPP)
「補足資料 1. DXライブラリを使ったプロジェクトを作ろう」
http://dixq.net/g/h_01.html
などを参考に、フォームの作成をしました。メインのコードは以下の通りです。

コード:

/* test.h */
#pragma once
#include "DxLib.h"
int WINAPI CPPForm(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);

コード:

/* test.cpp */
#pragma once
#include "test.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
	int ret = CPPForm(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
	return 0;
}

int WINAPI CPPForm(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
	ChangeWindowMode(TRUE); // ウィンドウモードに設定
	DxLib_Init();	// DXライブラリ初期化処理
	WaitKey();	// キー入力待ち
	DxLib_End();	// DXライブラリ終了処理
	return 0;
}
② 呼び出す側のC#フォームの作成(プロジェクト名:CS)
デザイナでボタンbutton1を設置し、そのクリックイベントにて、

コード:

/* Form1.cs */
using System;
using System.Windows.Forms;

namespace CS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //作ったフォームをこんな感じで呼び出したい
            CPPForm cppform = new CPPForm();
            cppform.Show();
        }
    }
}
以上のようなイメージで、CPPプロジェクトからフォームの呼び出しを行いたいのですが、このままでは、Main関数が被ったり引数の問題等で呼び出せません。
CPPのプロパティにて、「全般」→「構成の種類」を「アプリケーション (.exe)」から「ダイナミック ライブラリ (.dll)」に変更し、.dllとして参照してみると、
「"D:\~~CPP.dll"への参照を追加できませんでした。ファイルがアクセス可能で、有効なアセンブリまたはCOMコンポーネントであることを確認してください。」
というエラーが出ます。

ちなみに、以下のコードによりC++でWindowsフォームを作成すると、C#側から問題なく呼び出すことが出来ました。

コード:

/* CPPForm.h */
#pragma once

namespace CPP {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// CPPForm の概要
	/// </summary>
	public ref class CPPForm : public System::Windows::Forms::Form
	{
	public:
		CPPForm(void)
		{
			InitializeComponent();
		}

	protected:
		~CPPForm()
		{
			if (components)
			{
				delete components;
			}
		}

	private:
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		void InitializeComponent(void)
		{
			this->components = gcnew System::ComponentModel::Container();
			this->Size = System::Drawing::Size(300,300);
			this->Text = L"CPPForm";
			this->Padding = System::Windows::Forms::Padding(0);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
		}
#pragma endregion
	};
}

どのようにすれば、C#側からC++で作成したDirectXで描画されるフォームを呼び出せるのでしょうか。
DirectXを全てC#上で書けばもちろん出来ます。
しかし、DirectXプログラミングの参考となるものがC++で書かれたものがほとんどなのでC++で書きたいが、機能の追加先となるアプリケーションが既にC#で作成されていて全ての移行が大変という現状です。

条件が限定的ですが,何かご助言を頂ければ幸いです。宜しくお願い致します。

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: C++で作ったフォームをC#フォームから呼び出したい

#2

投稿記事 by YuO » 8年前

Windows APIの世界ではフォームという言葉を使わない (Windowと呼ぶ) のですが……。
それはさておき。

基本的な,C++でDLLを作ってC#から呼び出す方法は理解されていますか。
つまり,ひとつのソリューションに,[Visual C#]-[コンソール アプリケーション]と[Visual C++]-[Win32 プロジェクト] (種類:DLL) を入れて,
コンソールプログラムからDLLの関数を呼び出すことができますか。

これができないならば,WinFormsもDXLibも横に置いて,上記について理解することです。
さらに,「DLLの関数」と書いているように,関数を呼び出すのであって,C++側のクラスを利用することはできません。
どうしてもC++側のクラスを使いたいのであれば,C++/CLIのクラスライブラリでラッパーを作る必要があります。

上記ができるのであれば,その方法でDXLibを使って作られた関数を呼び出せばよいです。
ただし,DXLibがDLLから呼び出されることや,さらに言えば.NET Frameworkの環境から呼び出されて使うことを考慮されているかどうかはわかりません。
C++側でスレッドを作成して,その中でDXLibに関する事柄を完結させてしまった方が安全かも知れません。

閉鎖

“C言語何でも質問掲示板” へ戻る