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

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

新規登録して質問してみよう
ただいま回答率
85.50%
DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1109閲覧

WPFアプリケーションをdll化して、VC++で起動したい

taruto_11

総合スコア4

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2019/08/14 13:41

前提・実現したいこと

WPF(C#,MVVMパターン)で、自作ゲーム(C++)のデバッグ中に値を変更出来るGUIを作成しています。
このGUIをdllにして、C++側で自作ゲームと一緒に起動したいと考えています。
WPF側の関数をDllExportでC++側に表示して使用する所までは出来ましたが、以下のエラーが発生します。

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

ハンドルされない例外が 0x75E6C632 (KernelBase.dll) で発生しました(Game.exe 内): 0xE0434352 (パラメーター: 0x80131509, 0x00000000, 0x00000000, 0x00000000, 0x72810000)。

該当のソースコード

C#

1 public partial class App : Application 2 { 3 protected override void OnStartup( StartupEventArgs e ) 4 { 5 6 base.OnStartup( e ); 7 8 //ウィンドウをインスタンス化します 9 var window = new MainView(); 10 11 //ウィンドウに対する ViewModel をインスタンス化します 12 var view_model = new MainViewModel(); 13 14 //ウィンドウに対する ViewModel をデータコンテキストに指定します 15 window.DataContext = view_model; 16 17 //ウィンドウを表示する 18 window.Show(); 19 20 //ウィンドウを最前面に表示する 21 window.Activate(); 22 //ウィンドウを最前面に保持する 23 window.Topmost = true; 24 } 25 26 [DllExport] 27 public static void Create() 28 { 29 GUI.App app = new GUI.App(); 30 31 app.Run();//ここでエラーが発生する 32 } 33 34 }

C++

1 2 const TCHAR* pemodule = _T("./GUI/bin/Debug/x86/GUI.dll"); 3 HMODULE lib = LoadLibrary(pemodule); 4 5 typedef void(__cdecl *Create)(); 6 7 auto create = reinterpret_cast<Create>(GetProcAddress(lib, "Create")); 8 9 //window生成 10 create();

試したこと

WPF側の関数読み取りは成功しています。( Debug.WriteLine("OK") 等は通るため)
「App.xaml があると失敗する」と書いてあったサイトがあったので試しましたが、ダメでした。
色々書き換えた結果、 app.Run() と var window = new MainView(); の2つでエラーが発生することが分かりました。
DllExport ではなく C++/CLI で試しましたが、こちらでもダメでした。 (コードは残ってないです、すみません。)
dll内をデバッグ出来るようにしたかったのですが、今の所は出来ていません。

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

Visual Studio 2015

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

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

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

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

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

Zuishin

2019/08/14 14:11

C++/CLI で新しく作ってコードを残すのがいいと思います。
guest

回答1

0

自己解決

すみません、自己解決しました。
DllExportを使用した方法は一旦止めて、C++/CLIで再度行いましたが、私の環境では使用できませんでした。(チーム内の環境を変える必要があったため)
あまり詳しくは調べてないのですが、COMを使用した方法で解決出来ました。
特に参考にさせて頂いたサイトを貼っておきます。
コードは貼ってあるサイトを参考にしています。(どのように改良したか残してあります。活用してください。)

参考にさせて頂いたサイト

https://archive.fo/SWmZa
https://www.84kure.com/blog/2014/07/17/c-cからcのdllを呼ぶ方法/

C#

1 2using GUI.ViewModels; 3using GUI.Views; 4using System.Diagnostics; 5 6 7namespace GUI 8{ 9 10 //++ C++側に見せる関数を記述するクラス 11 public class Link 12 { 13 14 #region ウィンドウ生成 15 16 private GUI.App app = new GUI.App(); 17 18 public void Create() 19 { 20 app.Run(); 21 } 22 23 public void Delete() 24 { 25 app.Shutdown(); 26 } 27 28 #endregion ウィンドウ生成 29 30 } 31 32 33} 34

C++

1 2 3 4//!++ 追加 5#pragma comment(lib, "comsupp.lib") 6#pragma comment(lib, "comsuppw.lib") 7 8 9#include <Windows.h> 10#include <comutil.h> 11#include <objbase.h> 12 13//グローバル変数 14IDispatch *pIDisp = NULL; 15IUnknown *pIUnk = NULL; 16 17//プロトタイプ宣言 18int Init(void); 19long Finalize(void); 20//int Sum(int p_Number1, int p_Number2); 21void CreateGUIWindow(); 22 23int main() 24{ 25 //変数宣言 26 int l_Result = 0; 27 28 //初期処理 29 Init(); 30 31 //合計処理 32 //l_Result = Sum(5, 7); 33 CreateGUIWindow(); 34 35 //後処理 36 Finalize(); 37 38 39 return 0; 40} 41 42//***************************************************************************// 43//初期化関数 44//***************************************************************************// 45int Init(void) 46{ 47 CLSID clsid; 48 49 //COM初期化 50 CoInitialize(0); 51 52 HRESULT hr = S_OK; 53 54 //ProcIDからCLSIDを取得 55 //! (ネームスペース名.クラス名) 56 hr = CLSIDFromProgID(L"GUI.Link", &clsid); 57 if (FAILED(hr)) 58 { 59 return -1; 60 } 61 62 //Instanceの生成 63 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pIUnk); 64 if (FAILED(hr)) 65 { 66 return -2; 67 } 68 69 //インターフェースの取得(pIDispは共通変数) 70 hr = pIUnk->QueryInterface(IID_IDispatch, (void**)&pIDisp); 71 if (FAILED(hr)) 72 { 73 return -3; 74 } 75 76 //正常終了 77 return 0; 78} 79 80//***************************************************************************// 81//後始末処理 82//***************************************************************************// 83long Finalize(void) 84{ 85 pIDisp->Release(); 86 pIUnk->Release(); 87 CoUninitialize(); 88 return 0; 89} 90 91//***************************************************************************// 92//合計処理呼出処理 93//***************************************************************************// 94//int Sum(int num_1, int num_2) 95void CreateGUIWindow() 96{ 97 //DISPIDの取得(関数名の設定) 98 DISPID dispid = 0; 99 OLECHAR *Func_Name[] = { L"Create" };//? Create : 呼び出したい関数 100 HRESULT h_result = pIDisp->GetIDsOfNames(IID_NULL, Func_Name, 1, LOCALE_SYSTEM_DEFAULT, &dispid); 101 if (FAILED(h_result)) 102 { 103 return; 104 } 105 106 //パラメータ作成 107 //! 引数の設定 108 DISPPARAMS parameter; 109 memset(&parameter, 0, sizeof(DISPPARAMS)); 110 111 parameter.cNamedArgs = 0; 112 parameter.rgdispidNamedArgs = NULL; 113 parameter.cArgs = 0; //! 呼び出す関数の引数の数 114 115 //+ 引数設定 詳しくは http://marupeke296.com/IKDADV_CPP_VARIANT.html 116 //! 呼び出す引数分、配列を確保する 117 //! (順番に注意…逆になる) 118 //VARIANTARG* pVarg = new VARIANTARG[parameter.cArgs]; 119 120 ////+ 後ろから1つ目の引数設定 121 ////? vt : 引数の型によって種類を変える必要がある 122 ////? intVal : 引数がint型であるため 123 //pVarg[0].vt = VT_I4; 124 //pVarg[0].intVal = num_2; 125 126 ////+ 後ろから2つ目の引数設定 127 //pVarg[1].vt = VT_I4; 128 //pVarg[1].intVal = num_1; 129 130 ////+ 設定した引数分の情報を格納する 131 //parameter.rgvarg = pVarg; 132 133 //! 関数の結果が入っている 134 //VARIANT vResult; 135 //VariantInit(&vResult); 136 137 //呼び出し 138 //!? nullptr : 元はvResultが入っていました 139 pIDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &parameter, nullptr, NULL, NULL); 140 141 //delete[] pVarg; 142 143 //return vResult.intVal; 144} 145

投稿2019/08/15 20:47

taruto_11

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問