興味本位でGo言語に触れてみようと思う。WSLで64bit Windows DLLを生成してしてみる。で、DllMainが必要な時にどうするかってところまで。
参考サイトはこちら(https://qiita.com/h6591/items/18620f0ac93ea1ae219b)。で、もうメンドクサイので作ったファイルを載せていく。
dlltry1.go
- package main
-
- import "C"
-
- //export tasu
- func tasu(a int,b int) int {
- return a+b
- }
-
- func main(){
- }
Makefile
- OPT_CC= CC=x86_64-w64-mingw32-gcc
- #OPT_CC= CC=i686-w64-mingw32-gcc
- OPT_CGO= CGO_ENABLED=1
- OPT_OS= GOOS=windows
- OPT_ARCH= GOARCH=amd64
- #OPT_ARCH= GOARCH=386
- GOFLAGS=build -buildmode=c-shared
- #GOFLAGS=build -ldflags "-s -w" -buildmode=c-shared
- GO=go
- SRCS=dlltry1.go
- TARGET=dlltry1.dll
-
- $(TARGET) : $(SRCS)
- $(OPT_CC) $(OPT_CGO) $(OPT_OS) $(OPT_ARCH) $(GO) $(GOFLAGS) -o $(TARGET) $(SRCS)
-
- clean :
- rm dlltry1.dll dlltry1.h
dlltest1.c
- #include <stdio.h>
- #include <stdint.h>
- #include <windows.h>
- typedef int (__stdcall *tasu_type)(int a,int b);
- HMODULE dll;
- tasu_type tasu;
-
- int main(int argc,char** argv){
- int r;
- dll=LoadLibrary("dlltry1.dll");
- tasu=(tasu_type)GetProcAddress(dll,"tasu");
- r=tasu(55,41);
- printf("%d\n",r);
- return 0;
- }
で、ビルドしてテストアプリをコンパイルして実行してみる。
make
x86_64-w64-mingw32-gcc dlltest1.c
ls -la
./a.exe
はい。うまくいきました。よかった。
それで今度は、DllMainでDLL_PROCESS_ATTACHとかのイベントで動作させたいときにどうするかってのだけど、cgo使うわけでいっそのことCで書いちゃえば良いってわけだ。で、やってみる。
dlltry2.go
- package main
-
- import "C"
-
- //export tasu
- func tasu(a int,b int) int {
- return a+b
- }
-
- func main(){
- }
dllmain.go
- package main
-
- /*#include "dllmain.h"*/
- import "C"
dllmain.h
- #include <stdio.h>
- #include <stdint.h>
- #include <windows.h>
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- int32_t initialize(){
- ZeroMemory(&si,sizeof(si));
- si.cb=sizeof(si);
- ZeroMemory(&pi,sizeof(pi));
- if(!CreateProcess(NULL,"calc.exe",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){
- printf( "(C)CreateProcess failed (%d).\n", GetLastError() );
- return -1;
- }
- return 0;
- }
- void finalize(){
- // Close process and thread handles.
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- }
-
- BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved ){
- switch( fdwReason )
- {
- case DLL_PROCESS_ATTACH:
- printf("DLL_PROCESS_ATTACH\n");
- initialize();
- break;
-
- case DLL_THREAD_ATTACH:
- printf("DLL_THREAD_ATTACH\n");
- break;
-
- case DLL_THREAD_DETACH:
- printf("DLL_THREAD_DETACH\n");
- break;
-
- case DLL_PROCESS_DETACH:
- printf("DLL_PROCESS_DETACH_1\n");
- if (lpvReserved != NULL){
- break; // do not do cleanup if process termination scenario
- }
- printf("DLL_PROCESS_DETACH_2\n");
- finalize();
- break;
- }
- return TRUE;
- }
Makefile
- OPT_CC= CC=x86_64-w64-mingw32-gcc
- #OPT_CC= CC=i686-w64-mingw32-gcc
- OPT_CGO= CGO_ENABLED=1
- OPT_OS= GOOS=windows
- OPT_ARCH= GOARCH=amd64
- #OPT_ARCH= GOARCH=386
- GOFLAGS=build -buildmode=c-shared
- #GOFLAGS=build -ldflags "-s -w" -buildmode=c-shared
- GO=go
- #SRCS=dll64wdllmain.go dllmain.go
- SRCS=dlltry2.go dllmain.go
- TARGET=dlltry2.dll
-
- $(TARGET) : $(SRCS)
- $(OPT_CC) $(OPT_CGO) $(OPT_OS) $(OPT_ARCH) $(GO) $(GOFLAGS) -o $(TARGET) $(SRCS)
- clean :
- rm dlltry2.dll dlltry2.h
-
dlltest2.c
- #include <stdio.h>
- #include <stdint.h>
- #include <windows.h>
- typedef int (__stdcall *tasu_type)(int a,int b);
- HMODULE dll;
- tasu_type tasu;
-
- int main(int argc,char** argv){
- int r;
- dll=LoadLibrary("dlltry2.dll");
- tasu=(tasu_type)GetProcAddress(dll,"tasu");
- r=tasu(55,41);
- printf("%d\n",r);
- return 0;
- }
make
x86_64-w64-mingw32-gcc dlltest2.c
ls -la
./a.exe
そすっと、
電卓は立ち上がるわコンソールにいろいろ出力されるわで、、、期待通り、、、です(∩´∀`)∩ワーイ、、、(DLL_PROCESS_DETACH_2が出力されていないのがなんでなのか、、、ま、いいか)
、、、突然始まったこの活動、実はある目的に向かっているんだけど、こんどの土曜日には何だったのか忘れているかもしれない。なら、ここに書いておけば?ってのも思うけど、まだやれてもいないのに書いちゃって検索で引っかかると申し訳ないじゃんね。だから書けない。検索して、見つけたーって開いたら「、、、をやるつもり」的な記述だと殺意に近い憎悪をおぼえるよね(´∀`)
0 件のコメント:
コメントを投稿