トップページ > 記事閲覧
dllからDxlibを使用したい
名前:東海鉄道 日時: 2022/07/30 21:24

お久しぶりです 今回相談したいのはDllからDxLibを使用したい時にどうすればいいのかです 1ソリューションの中に UseDll(以下U)プロジェクトとDll(以下D)プロジェクトがありどちらも単体ではDxLibを使用できるはずの設定がされています DプロジェクトのみDllとして作成しています Uプロジェクトのファイルは1つで /*-UseDll.cpp-*/ #include "DxLib.h" #define dlopen(P,G) LoadLibrary(P) #define dlsym(D,F) GetProcAddress((HMODULE)D,F) #define dlclose(D) FreeLibrary((HMODULE)D) typedef void (*FUNC)(); int main() { ChangeWindowMode(true); if (DxLib_Init()) { return 1; }; SetDrawScreen(DX_SCREEN_BACK); HMODULE dll=dlopen("Dll.dll", ""); if (dll == NULL) { return 1; } FUNC func = (FUNC)dlsym(dll, "func"); DrawString(0, 10, "exe", GetColor(255, 255, 255)); func(); ScreenFlip(); DxLib_End(); return 0; } です Dプロジェクトのファイルは2つで /*-Dll.cpp-*/ #include "DxLib.h" typedef void (*FUNC)(); extern "C" { void func() { DrawString(0, 10, "Dll", GetColor(255, 255, 255)); } } /*-Dll.def-*/ EXPORTS func となっております ScreenFlip();後にブレークポイントを貼ってみてみると画面にはexeとのみ表示されていてdllからDxLibを使用できません やり方が悪いのか構造上できないのかどちらなのでしょうか やり方が悪いようでしたら良いやり方を教えてください
メンテ

Page: 1 |

Re: dllからDxlibを使用したい ( No.1 )
名前:管理人 日時:2022/07/31 03:26

東海鉄道さんが試された構成ですと、UseDll.exe と Dll.dll の2つにそれぞれDXライブラリが存在する事になるので Dll.cpp 内の DrawString は『まだ DxLib_Init が呼ばれていないから DrawString が失敗した』状態になり、正常に動作しません ただ、では Dll.cpp でも DxLib_Init を呼べば良いのかというとそうでもなく、DXライブラリが作成するウィンドウが 『Dll.cpp の DxLib_Init で作成されたウィンドウ』と『UseDll.cpp の DxLib_Init で作成されたウィンドウ』とで合計2つになり、 Dll.cpp で行われた描画は Dll.cpp の DxLib_Init で作成されたウィンドウへ UseDll.cpp で行われた描画は UseDll.cpp の DxLib_Init で作成されたウィンドウへ反映され、 お互いの描画結果や LoadGraph などで読み込むグラフィックハンドルなどを共有することはできません なので、DXライブラリの関数を呼ぶのは Dll.cpp 側だけにする必要があります Dll.cpp 側でのみDXライブラリの関数を呼ぶようにする場合は、DxLib_Init も ScreenFlip も Dll.cpp 側に ラッパー関数を用意して、そのラッパー関数を UseDll.cpp 側で呼び、DXライブラリの関数は全て Dll.cpp 側で実行されるようにします /*-UseDll.cpp-*/ #include "DxLib.h" #define dlopen(P,G) LoadLibrary(P) #define dlsym(D,F) GetProcAddress((HMODULE)D,F) #define dlclose(D) FreeLibrary((HMODULE)D) typedef void (*FUNC)(); typedef int (*DLL_ChangeWindowMode)(int); typedef int (*DLL_DxLib_Init)(); typedef int (*DLL_SetDrawScreen)(int); typedef int (*DLL_DrawString)(int, int, const char *, int); typedef int (*DLL_ScreenFlip)(); typedef int (*DLL_DxLib_End)(); int main() { HMODULE dll=dlopen("Dll.dll", ""); if (dll == NULL) { return 1; } FUNC func = (FUNC)dlsym(dll, "func"); DLL_ChangeWindowMode Dll_ChangeWindowMode = (DLL_ChangeWindowMode)dlsym(dll, "Dll_ChangeWindowMode"); DLL_DxLib_Init Dll_DxLib_Init = (DLL_DxLib_Init)dlsym(dll, "Dll_DxLib_Init"); DLL_SetDrawScreen Dll_SetDrawScreen = (DLL_SetDrawScreen)dlsym(dll, "Dll_SetDrawScreen"); DLL_DrawString Dll_DrawString = (DLL_DrawString)dlsym(dll, "Dll_DrawString"); DLL_ScreenFlip Dll_ScreenFlip = (DLL_ScreenFlip)dlsym(dll, "Dll_ScreenFlip"); DLL_DxLib_End Dll_DxLib_End = (DLL_DxLib_End)dlsym(dll, "Dll_DxLib_End"); Dll_ChangeWindowMode(true); if (Dll_DxLib_Init()) { return 1; }; Dll_SetDrawScreen(DX_SCREEN_BACK); Dll_DrawString(0, 10, "exe", GetColor(255, 255, 255)); func(); Dll_ScreenFlip(); Dll_DxLib_End(); return 0; } /*-Dll.cpp-*/ #include "DxLib.h" extern "C" { void func() { DrawString(0, 10, "Dll", GetColor(255, 255, 255)); } int Dll_ChangeWindowMode( int Flag ) { return ChangeWindowMode( Flag ) ; } int Dll_DxLib_Init() { return DxLib_Init() ; } int Dll_SetDrawScreen( int TargetScreen ) { return SetDrawScreen( TargetScreen ) ; } int Dll_DrawString( int x, int y, const char *String, int Color ) { return DrawString( x, y, String, Color ) ; } int Dll_ScreenFlip() { return ScreenFlip() ; } int Dll_DxLib_End() { return DxLib_End() ; } } /*-Dll.def-*/ EXPORTS func Dll_ChangeWindowMode Dll_DxLib_Init Dll_SetDrawScreen Dll_DrawString Dll_ScreenFlip Dll_DxLib_End よろしければお試しください m(_ _)m
メンテ
Re: dllからDxlibを使用したい ( No.2 )
名前:東海鉄道 日時:2022/08/01 21:29

返信遅くなりました 間違いなく動作しました ありがとうございます 何らかの方法を使ってexe側からDxLibを初期化することはできないでしょうか ソースを書き換えるものでも構いませんし絶対に無理なら諦めます 何か方法はあるのでしょうか?
メンテ
Re: dllからDxlibを使用したい ( No.3 )
名前:管理人 日時:2022/08/02 00:27

少し考えてみたのですが、Dll側に exe側のDXライブラリの関数のアドレスを登録する形にすることで exe側でDXライブラリの関数を呼ぶようにすることが出来ました /*-UseDll.cpp-*/ #include "DxLib.h" #define dlopen(P,G) LoadLibrary(P) #define dlsym(D,F) GetProcAddress((HMODULE)D,F) #define dlclose(D) FreeLibrary((HMODULE)D) struct DxLibFunction { int ( *DrawGraph )( int x, int y,int GrHandle, int TransFlag ) ; int ( *DrawExtendGraph )( int x1, int y1, int x2, int y2, int GrHandle, int TransFlag ) ; int ( *DrawString )( int x, int y, const char *String, unsigned int Color, unsigned int EdgeColor ); int ( *DrawBox )( int x1, int y1, int x2, int y2, unsigned int Color, int FillFlag ) ; }; typedef void (*FUNC)(); typedef void (*DLL_RegisterDxLibFunction)( const DxLibFunction *DxLibFunc ); int main() { HMODULE dll=dlopen("Dll.dll", ""); if (dll == NULL) { return 1; } FUNC func = (FUNC)dlsym(dll, "func"); DxLibFunction fc; fc.ChangeWindowMode = ChangeWindowMode ; fc.DrawGraph = DrawGraph; fc.DrawExtendGraph = DrawExtendGraph; fc.DrawString = DrawString; fc.DrawBox = DrawBox; DLL_RegisterDxLibFunction Dll_RegisterDxLibFunction = (DLL_RegisterDxLibFunction)dlsym(dll, "RegisterDxLibFunction"); Dll_RegisterDxLibFunction( &fc ); ChangeWindowMode(true); if (DxLib_Init()) { return 1; }; SetDrawScreen(DX_SCREEN_BACK); DrawString(0, 10, "exe", GetColor(255, 255, 255)); func(); ScreenFlip(); DxLib_End(); return 0; } /*-Dll.cpp-*/ #include "DxLib.h" struct DxLibFunction { int ( *DrawGraph )( int x, int y,int GrHandle, int TransFlag ) ; int ( *DrawExtendGraph )( int x1, int y1, int x2, int y2, int GrHandle, int TransFlag ) ; int ( *DrawString )( int x, int y, const char *String, unsigned int Color, unsigned int EdgeColor ); int ( *DrawBox )( int x1, int y1, int x2, int y2, unsigned int Color, int FillFlag ) ; } DxFunc ; typedef void (*FUNC)(); extern "C" { void func() { DxFunc.DrawString(0, 10, "Dll", GetColor(255, 255, 255)); } void RegisterDxLibFunction( const DxLibFunction *DxLibFunc ) { DxFunc = *DxLibFunc; } } /*-Dll.def-*/ EXPORTS func RegisterDxLibFunction
メンテ
Re: dllからDxlibを使用したい ( No.4 )
名前:東海鉄道(解決済み) 日時:2022/08/13 20:59

返信大変遅くなりました(え、この間何してたかって?↑の事ライブラリにしたり既存のライブラリに←のライブラリ対応化工事したりBveで遊んだりしてました) 教えていただいた方法でexeからDxLibを初期化できましたありがとうございました
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存