- ベストアンサー
バイナリ→構造体
2chの回答
- 2ch
- ベストアンサー率51% (64/125)
追記 以前のサンプルはこちらの勘違いでActiveXExeで作ってしまったんだけど、 OCX化指令を出している先輩社員もいるのだから、読み替えてくれると思って わざわざ再投稿しなかったんだけど、なんかうるさいので、作り直し。 でもほとんど差はなし っていうか、ActiveX.DLLで通るならそれからOCXなんて、当たり前にできます。 「AcitveXDLLのインターフェイスに肉付けしたのがOCX」 だから、AcitveXDLLにできて、OCXにできないなんてこたぁありえません。 AcitveXEXEも同じこと。 ↓↓↓↓↓↓↓↓ 重要ここから ↓↓↓↓↓↓↓↓ 「反論するなら、意味も無く『無茶苦茶』発言はご勘弁」 「もしあるなら、調査・結果を書いた上でお願いします」 ↑↑↑↑↑↑↑↑ 重要ここまで ↑↑↑↑↑↑↑↑↑ Project1(EXE) ├Form1 │└UserControl1(Project2を参照し、コントロールを貼り付け) └Module1(EXEとOCX兼用) Project2(OCX) ├UserControl1 └Module1(EXEとOCX兼用) '''--------------------------------------------- '''---------- Project1.Form1 ここから ---------- '''--------------------------------------------- Option Explicit Private pProcID As Long Private hProcess As Long Private pShared As Long Private pSharedLen As Long Private Type typData a As Long b As Long c As Long End Type Private pDat As typData '別アプリ起動 Private Sub Command1_Click() On Error GoTo PGMERR Dim strWk As String '共有メモリに値を書き込む If Not memWrite(hProcess, pShared, VarPtr(pDat), pSharedLen) Then Call MsgBox("共有メモリへの書き込み失敗") GoTo PGMEND End If 'ActiveXをたたく 'プロセスID/配列要素数/共有メモリ先頭ポインタ If Not Me.UserControl11.RunExec(pProcID, pShared, strWk) Then GoTo PGMEND End If MsgBox strWk PGMEND: Exit Sub PGMERR: Call MsgBox(Err.Description, vbCritical) GoTo PGMEND End Sub 'ロード Private Sub Form_Load() Me.Command1.Caption = "ActiveX起動" Me.Command1.Enabled = False 'プロセスIDを取得する If Not GetThreadProcessId(Me.hwnd, pProcID) Then Call MsgBox("プロセス情報取得失敗") GoTo PGMEND End If '共有メモリオープン pSharedLen = Len(pDat) If Not memOpen(pProcID, pSharedLen, hProcess, pShared) Then Call MsgBox("共有メモリ確保失敗") GoTo PGMEND End If 'ダミーの値をセット Call setValues Me.Command1.Enabled = True PGMEND: End Sub 'アンロード Private Sub Form_Unload(Cancel As Integer) Call memFree(hProcess, pShared) End Sub 'ダミー値セット Private Sub setValues() With pDat .a = 2 .b = 4 .c = 6 End With End Sub '''--------------------------------------------- '''---------- Project1.Form1 ここまで ---------- '''--------------------------------------------- '''--------------------------------------------- '''---------- Project2.UserControl1 ここから --- '''--------------------------------------------- Option Explicit Private Type typData a As Long b As Long c As Long End Type Private pDat As typData 'メイン部 Public Function RunExec(ByVal inProcID As Long, ByVal inShared As Long, ByRef otBuff As String) As Boolean On Error GoTo PGMERR If Not memDataRead(inProcID, inShared, otBuff) Then GoTo PGMEND End If RunExec = True PGMEND: Exit Function PGMERR: Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpContext, Err.HelpFile GoTo PGMEND End Function '読み取りと画面反映 Private Function memDataRead(ByVal inAppID As Long, ByVal lngMemPointer As Long, ByRef otBuff As String) As Boolean On Error GoTo PGMEND Dim hProcess As Long Dim dwSize As Long Dim strBuff As String otBuff = "" 'メモリサイズを取得 dwSize = Len(pDat) '共有メモリ確保 If Not procOpen(inAppID, hProcess) Then Call MsgBox("共有メモリ確保失敗") GoTo PGMEND End If '共有メモリから値を読み込む If Not memRead(hProcess, lngMemPointer, VarPtr(pDat), dwSize) Then Call MsgBox("共有メモリからの読み込む失敗") GoTo PGMEND End If 'デバッグ用 With pDat strBuff = "" strBuff = strBuff & "受けデータ" & vbCrLf strBuff = strBuff & " A:" & .a & vbCrLf strBuff = strBuff & " B:" & .b & vbCrLf strBuff = strBuff & " C:" & .c & vbCrLf End With otBuff = strBuff memDataRead = True PGMEND: Call procFree(hProcess) Exit Function PGMERR: Call procFree(hProcess) Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpContext, Err.HelpFile GoTo PGMEND End Function '''--------------------------------------------- '''---------- Project2.UserControl1 ここまで --- '''--------------------------------------------- '''----------------------------------------------- '''---------- Project1.Module1 ここから ---------- '''---------- Project2.Module1 ここから ---------- '''---------- 二つのプロジェクトで必要 ---------- '''----------------------------------------------- Option Explicit Private Declare Function OpenProcess Lib "kernel32" ( _ ByVal dwDesiredAccess As Long, _ ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Private Declare Function VirtualAllocEx Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal flAllocationType As Long, _ ByVal flProtect As Long) As Long Private Declare Function VirtualFreeEx Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal dwFreeType As Long) As Long Private Declare Function GetWindowThreadProcessId Lib "user32" ( _ ByVal hwnd As Long, _ ByRef lpdwProcessId As Long) As Long Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long Private Declare Function WriteProcessMemory Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpBaseAddress As Long, _ ByVal lpBuffer As Long, _ ByVal nSize As Long, _ ByRef lpNumberOfBytesWritten As Long) As Long Private Declare Function ReadProcessMemory Lib "kernel32" ( _ ByVal hProcess As Long, ByVal lpBaseAddress As Long, _ ByVal lpBuffer As Long, _ ByVal nSize As Long, _ ByRef lpNumberOfBytesWritten As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000 Private Const SYNCHRONIZE As Long = &H100000 Private Const PROCESS_TERMINATE As Long = &H1 Private Const PROCESS_CREATE_THREAD As Long = &H2 Private Const PROCESS_SET_SESSIONID As Long = &H4 Private Const PROCESS_VM_OPERATION As Long = &H8 Private Const PROCESS_VM_READ As Long = &H10 Private Const PROCESS_VM_WRITE As Long = &H20 Private Const PROCESS_DUP_HANDLE As Long = &H40 Private Const PROCESS_CREATE_PROCESS As Long = &H80 Private Const PROCESS_SET_QUOTA As Long = &H100 Private Const PROCESS_SET_INFORMATION As Long = &H200 Private Const PROCESS_QUERY_INFORMATION As Long = &H400 Private Const PROCESS_ALL_ACCESS As Long = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF Private Const PAGE_NOACCESS As Long = &H1 Private Const PAGE_READONLY As Long = &H2 Private Const PAGE_READWRITE As Long = &H4 Private Const PAGE_WRITECOPY As Long = &H8 Private Const PAGE_EXECUTE As Long = &H10 Private Const PAGE_EXECUTE_READ As Long = &H20 Private Const PAGE_EXECUTE_READWRITE As Long = &H40 Private Const PAGE_EXECUTE_WRITECOPY As Long = &H80 Private Const PAGE_GUARD As Long = &H100 Private Const PAGE_NOCACHE As Long = &H200 Private Const PAGE_WRITECOMBINE As Long = &H400 Private Const MEM_COMMIT As Long = &H1000 Private Const MEM_RESERVE As Long = &H2000 Private Const MEM_DECOMMIT As Long = &H4000 Private Const MEM_RELEASE As Long = &H8000 Private Const MEM_FREE As Long = &H10000 Private Const MEM_PRIVATE As Long = &H20000 Private Const MEM_MAPPED As Long = &H40000 Private Const MEM_RESET As Long = &H80000 Private Const MEM_TOP_DOWN As Long = &H100000 Private Const MEM_4MB_PAGES As Long = &H80000000 'プロセスオブジェクトのハンドルを開く Public Function procOpen(ByVal inAppID As Long, otProc As Long) As Boolean otProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, inAppID) If otProc = 0 Then GoTo PGMEND End If procOpen = True PGMEND: End Function 'プロセスオブジェクトのハンドルを開放する Public Sub procFree(inProc As Long) Call CloseHandle(inProc) inProc = 0 End Sub '共有メモリをオープン Public Function memOpen(ByVal inAppID As Long, ByVal inSize As Long, otProc As Long, otSharedAddress As Long) As Boolean '共有メモリをクローズする Call memFree(otProc, otSharedAddress) 'プロセスオブジェクトのハンドルを開く If Not procOpen(inAppID, otProc) Then GoTo PGMEND End If '共有メモリを開放する otSharedAddress = VirtualAllocEx(otProc, 0, inSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) If otSharedAddress = 0 Then GoTo PGMEND End If memOpen = True PGMEND: If Not memOpen Then Call memFree(otProc, otSharedAddress) End If End Function '共有メモリをクローズ Public Sub memFree(inProc As Long, inSharedAddress As Long) 'クローズ Call VirtualFreeEx(inProc, inSharedAddress, 0, MEM_RELEASE) inSharedAddress = 0 'プロセスオブジェクトのハンドルを開放する Call procFree(inProc) End Sub '共有メモリ領域に書き込む Public Function memWrite(ByVal inProc As Long, ByVal inSharedAddress As Long, ByVal inMemPnt As Long, ByVal inSize As Long, Optional otSize As Long) As Boolean Dim lngSts As Long otSize = 0 lngSts = WriteProcessMemory(inProc, inSharedAddress, ByVal inMemPnt, inSize, otSize) memWrite = (lngSts <> 0) End Function '共有メモリ領域から読み込む Public Function memRead(ByVal inProc As Long, ByVal inSharedAddress As Long, ByVal inMemPnt As Long, ByVal inSize As Long, Optional otSize As Long) As Boolean Dim lngSts As Long otSize = 0 lngSts = ReadProcessMemory(inProc, inSharedAddress, ByVal inMemPnt, inSize, otSize) memRead = (lngSts <> 0) End Function 'ハンドルから、プロセスIDとスロッドIDを取得する Public Function GetThreadProcessId(ByVal inWnd As Long, Optional otProcID As Long, Optional otThred As Long) As Boolean otProcID = 0 otThred = 0 otThred = GetWindowThreadProcessId(inWnd, otProcID) GetThreadProcessId = (otThred <> 0) End Function '''----------------------------------------------- '''---------- Project1.Module1 ここまで ---------- '''---------- Project2.Module1 ここまで ---------- '''---------- 二つのプロジェクトで必要 ---------- '''-----------------------------------------------
関連するQ&A
- 構造体→文字列→構造体 をする方法
VB6.0の話です。 不特定の構造体を文字列(String)に格納し、これを最初の構造体に戻す事はできませんか? 具体的には「共有メモリを使い構造体を文字列にして格納>別ウインドウで文字列を取得して構造体に戻す」と言う事をやりたいんです。 共有メモリに不特定の構造体をいれる方法でもいいんですが…VALIANTだとサイズが大きすぎて実用性がありませんし、違う主旨の質問をするのも良くないので回答はあくまで「構造体→文字列→構造体 をする方法」と言う事でお願いします。
- ベストアンサー
- Visual Basic
- HOSTENT構造体を宣言する必要はないのですか?
ネットワークプログラミングを勉強しているのですが,ソケットを用いた通信のサンプルで, HOSTENT *lphost として,HOSTENT構造体へのポインタを宣言して, lphost = gethostbyname(ホスト名の文字列); で,サーバーのアドレスをHOSTENT構造体にセットするとあります。 構造体へのポインタを宣言しても,構造体自体の領域は確保されないのではないかと思うのですが,gethostbyname関数が返すポインタは,いったい誰がどこに確保した領域を指しているのか,そしてその領域はいつまで保持されるのか,よく理解できません。構造体そのものを宣言せずに,それへのポインタを宣言し,それに関数の戻り値を代入するというのが,よく理解できないです。どなたか解説していただけると幸いです。
- ベストアンサー
- C・C++・C#
- VB2008: 構造体に関連して・・・。
VB.Net を知って60日という初学者です。 プログラマではなくデザイナ。 ですから、未だに Sub Main() で基本事項の確認中です。 フォームなどの演習は、まーだ、当分はしない予定です。 さて、質問は構造体に関するMSDN の記述です。 >構造体の要素が文字列型 (String) やオブジェクト型 (Object) などの参照型である場合は、 >データへのポインタがコピーされます。 この下り。 「なんでポインタがコピーされるんや」という疑問を抱きました。 ・文字列型にプロパティやメソッドという機能を付加するためにクラス型にした。 ・クラス型は、「・・・・」ということで参照型。と ・「・・・・」と同じ理由。 というように背景を推測しました。 この推測も単なるど素人の推測。 当を得たいるか?実に怪しい物。 仮に当らずとも遠からずとしても、肝心の「・・・・」がわかりません。 この辺りに関して、「このように考えてたらよい」という回答がありましたらお願いします。
- ベストアンサー
- Visual Basic
- VB6でポインタ?
VB6でポインタを扱う関数 VarPtrがあるのですが、使えるデータ型は何があるのでしょうか? 仕様なのか、動的配列のポインタが取得できません。 dim kosuu() as integer redim kosuu(50) dim pointer as long pointer = VarPtr( kosuu() ) 'エラー VB6でポインタを扱う場面は例えばどんな場合があるか知りたいです。 ポインタは使わない(使ってはいけない)のが基本でしょうか。
- ベストアンサー
- Visual Basic
- VB .Netの構造体について
構造体について教えて下さい。 クラスで構造体を作成しました。 クラスでIniファイルを読み込み、Formのボタンを押した処理の中で構造体を読み込みたいのですが、何をしても空白(Nothing)になります。 クラスの中では格納されたままなのに・・・。 違う場所で構造体を呼んだときは別の処理がいるのでしょうか? それともVB .Netの仕様なのでしょうか?
- ベストアンサー
- Visual Basic
- 構造体について
構造体について分からない点があり,教えて頂きたく投稿いたします. 現在,以下のような構造体を作成しています. typedef struct{ int data; struct node *NEXT; }node; また,それを管理するためのリストを以下の構造体にて宣言しました. typedef struct{ node *crnt; node *last; }node_list; また,使用する関数内での宣言は以下の通りです. node_list *non_dscvr_node_list; //未探査ノードを格納する node *crt_dscvr_node; //現在探査中のノードを示す node *start; そして, start->data = 10; start->NEXT = NULL; non_dscvr_node_list->crnt = start; non_dscvr_node_list->last = start; : : crt_dscvr_node = non_dscvr_node_list->crnt; non_dscvr_node_list->crnt = crt_dscvr_node->NEXT; //ここでエラーがでる. エラーの詳細は以下の通りです. warning: assignment from incompatible pointer type 私としては,リストに格納されている先頭ノードをポップして,次のノードを先頭にしたつもりだったのですが,ポインタタイプに互換性がないと怒られてしまいました. 少し調べては見ましたが,nodeの構造体を管理するために別に構造体を定義しているページがあまり見あたりません. 従って,そのようなページがあれば教えて頂きたいと思います. このような方法はあまりよくないのでしょうか. 併せて教えていただけますようお願いいたします.
- ベストアンサー
- C・C++・C#
- C#の構造体に関して
C#の構造体に関して C#で構造体で配列を持ちたいと思い、宣言の仕方や使い方を 勉強していますが、どうしてもコンパイルは通るもののエラーと なってしまいます。 《ソース》 単純に構造体で宣言した"a"という配列に、"ABC"という文字列を 代入したいだけですが。。。 namespace テスト環境 { struct test { public string []a; } class Program { static void Main(string[] args) { test aaa = new test(); aaa.a[0] = "ABC"; } } } 配列の初期化等は、ようやく理解したつもりではいますが、構造体 が絡むとどうしてもわかりません。 どこをどのように修正したら良いかを教えて下さい。 初歩的な質問で申し訳ありませんが、よろしくお願いします。
- ベストアンサー
- C・C++・C#
- 構造体の初期化の時にポインタを入れるにはどうしたらいいですか?
構造体の初期化の時にポインタを入れるにはどうしたらいいですか? 例えば、このような構造体で↓ struct PACKET { uint16_t size; // データの長さ uint16_t *data; // データバイト列 }; 初期化の時にsizeとdataを入れるにはどうしたらいいのでしょうか? dataがuint16_t*じゃなくてchar*なら struct PACKET { uint16_t size; // データの長さ char *data; // データバイト列 }; struct PACKET p = { 5, "12345" }; というようにできるのですが・・・
- ベストアンサー
- C・C++・C#
- 構造体 アドレス
VC++6 こんにちは。構造体のアドレスを文字列ポインタで操作することに悩んでいます。下にソースの一部を書きます。 typedef struct{ char code[100]; int type; }AAA; typedef struct{ double method[4][3]; int area; }BBB; 複数の構造体があり、 BOOL CTestApp::File_Check(){ AAA aaa; ~ db.DB_regi(2, (char *)&aaa); ~ } void CData::DB_regi(int key, char *buff) { switch(key){ ~ case 2: sss.push_back(buff); //vector<char *> sss; break; } で、データを登録し、 int CTestApp::Data_Check() { ~ AAA aaa; db.DB_get(2, (char *)&aaa); ~ } void CData::DB_get(int key, char *buff) { switch(key){ ~ case 2: buff = sss[i]; break; ~ } で、構造体のアドレスを取得しようと思ったら、取得できませんでした。 //DB_getの中では、aaa = (AAA *)buff;とすれば指定の構造体を取得できる。 DB_get関数をどのようにしたら、Data_Check()で、登録した構造体を取得できるのか教えてください。長くなってすみません。
- ベストアンサー
- C・C++・C#