VBとDLL間でのポインタの受け渡しについて

このQ&Aのポイント
  • VBで開発を行っていますが、DLLとの間でポインタの引渡しで困っています。
  • DLLのTR_MR関数を使用してキーに基づいたデータを取得し、TR_MR_IT関数を使用してデータの各要素を取得する仕組みです。
  • VBでの宣言は、Tagset型を使用してトラップされたデータの読み込みとデータの要素化を行っています。
回答を見る
  • ベストアンサー

DLL<->VB間での受け渡し(文字列・ポインタ)

VBで開発を行っていますが、 DLL<->VBでのやり取りでポインタ?のの引渡しで困っております。 簡単に言うと、指定したキーで、内容(データ)を取出し、さらに 要素ごとにデータを取出すという仕組みです。 例ですが、DLLの仕様は TR_MR(No,Id,Buff)  Noは検索No.  Idは取出す位置  buffはデータバッファ領域のポインタ で、Idで指定された位置からデータをbuffに読み込む (戻り値は、buffにセットされたデータのバイトサイズ) TR_MR_IT(buff,Tagset,Dat) buffは先ほど取り込んだデータバッファ領域のポインタ Tagsetは項目識別子のポインタ Datはデータ上の1項目の文字列 と言う具合です。 VBでの宣言は =================================================== Private Type Tagset tagno As String * 3 Subf As String * 1 seq As Integer End Type Private Declare Function TR_MR Lib "tr.dll" (ByVal no As Integer, ByVal Id As Integer, ByVal buff As String) As Integer Private Declare Function TR_MR_IT Lib "tr.dll" (ByVal buff As String, ByRef tg As Tagset, ByVal dat As String) As Integer Dim buf_size As Integer Dim MR_buff As String MR_buff = String(65562, vbNullChar) buf_size = TR_MR(no, 1, MR_buff) Dim tg As Tagset Dim MR_size As Integer Dim MR_IT_buff As String tg.tagno = "001" tg.Subf = "A" tg.seq = 1 MR_IT_buff = String(12282, vbNullChar) MR_size = TR_MR_IT(MR_buff, tg, MR_IT_buff) =================================================== 長々と書いてしまいましたが、 何か、助言をいただければ幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • haporun
  • ベストアンサー率40% (230/562)
回答No.1

ポインタの何が困っているのか、この内容からでは理解しかねます・・・。 ○ 文字列はByValでポインタが渡される ○ 配列は先頭の要素をByRefでポインタが渡される ○ それ以外の変数もByRefでポインタが渡される この質問により、何が知りたいかなどを明記してください。

you-mi
質問者

お礼

haporunさん ありがとうございました。 原因は、VBの内容をよく理解していないために、 ご苦労をおかけしました。 今回の件は、文字列をそのまま引き渡していたため 見当違いの方向で進んでおりました。 他のQ&Aを参考にして Byte に変換しないと いけなかったようです。(ポインタはその後) 仕様に惑わされてしまっておりました。

関連するQ&A

  • VB .NetのDLL参照について

    名前付パイプの処理をしているのですが、DLLが参照できません。 Public Class ClsJi01   Public Declare Function MakePipe Lib "\DLL\Point.DLL" (ByVal pipe_name As String, ByVal buf_size As Integer, ByVal max_instances As Short, ByVal hpipe As Integer, ByVal err_code As Integer) As Integer  Public Sub M_Pipe()   Dim r As Integer   Dim rpipe As Integer   Dim err_code As Integer   r = MakePipe("\\.\pipe\RS04", 255, 16, rpipe, err_code)  End Sub End Class Point.DLLは以前VB6.0の時に使用していたDLLで自作です。 これで実行すると「オブジェクト参照がオブジェクト インスタンスに設定されていません。」と出ます。 どうしたら良いのでしょうか?

  • VB6でポインタ?

    VB6でポインタを扱う関数 VarPtrがあるのですが、使えるデータ型は何があるのでしょうか? 仕様なのか、動的配列のポインタが取得できません。 dim kosuu() as integer redim kosuu(50) dim pointer as long pointer = VarPtr( kosuu() ) 'エラー VB6でポインタを扱う場面は例えばどんな場合があるか知りたいです。 ポインタは使わない(使ってはいけない)のが基本でしょうか。

  • VB2005 から DLL を呼び出す

    VB 初心者です。 今、VB の練習ということで VB 2005 Express Edition を使って、個人用ブラウザをつくっています。Web ページの表示は Webbrowser コンポーネントを使っています。 その仕様で、閲覧先によって HTTP Proxy を変更するようになっています。(自分で決めたんですが) いろいろ調べてみると、urlmon.dll の UrlMkSetSessionOption() を呼べば自分のアプリケーション限定で Proxy を変更できるようだ、ということがわかりました。 古い VB など(VB 6 とか?)では、 Private Declare Sub UrlMkSetSessionOption Lib "urlmon.dll" _ (ByVal dwOption As Long, ByVal pBuffer As Any, _ ByVal dwBufferLength As Long, _ ByVal dwReserved As Long) このような感じで宣言するとかあったんですが、VB2005 では Any がダメだとか、 Type INTERNET_PROXY_INFO Dim dwAccessType As Long Dim lpszProxy As String Dim lpszProxyBypass As String End Type で Type はダメだとか、呼び出し側で、LenB を使おうとしたら使えないだとか、INTERNET_OPTION_PROXY の値がわからないなど、問題が山積みです。 上記 DLL を VB 2005 で使ったことがある人がいたら(またはわかる人)、使い方を教えてもらえないでしょうか?

  • DLL VBとC++

    VBAからVC++2005のDLLを呼び出すプログラムを書いています。 VB側で作成したcpp_proc関数を呼ぶとVBアプリ自体が落ちました。 DLLのreturnの直前に以下のMessageBoxで表示させるとそこまでは表示され、 リターンを押すと、落ちました。 VB側の引数の値 String * 8192が悪いのでしょうか? return直前まで動作していたので、DLLの戻り値に何か原因があるのでしょうか? ついでの質問ですが、DEFの @1は無くても動くのでしょうか? 意味が知りたいです。 // ----- C++ (DLL側) ----- int __stdcall cpp_proc(LPCSTR inp, LPSTR out) { ... 省略 MessageBox(0, "ここまで通過", "debug", MB_OK); return 0; } // ----- DEF ----- LIBRARY "example" DESCRIPTION 'テスト' EXPORTS ; 明示的なエクスポートはここへ記述できます cpp_proc @1 '----- VB側 ----- Public Declare Function cpp_proc Lib "example.dll" _ (ByVal inp As String, ByRef out As String) As Integer Public Sub Test() Dim ret As Integer Dim inp As String Dim out As String * 8192 ret = cpp_proc(inp, out) MsgBox("ret=[" & Cstr(ret) & "]"); End Sub

  • dllを使用しVB側に文字列を返す2

    No.280310の質問の続きになってしまいますが 「VCで作ったdllを使用し VBに文字列を返すことはできますか」 でVCで作ったdllをVBを呼び出す事ができるようになりました。 Declare宣言で疑問に思ったのですが Declare Function TxtCnt Lib "hoge.dll" (ByVal a As String) As Long aはなぜ値渡しなのでしょうか? 変数が書き換えられて戻ってくるので、byrefで指定していました。 それが問題が起こしていた原因一つでした。 ちなみにint型の数値をポインタで渡した場合はbyrefでうまくいきます。 ご教授願います。

  • VB6からVCで作成したDLLへのvoidポインタの受け渡し

    VB6でVCで作成されたDLLの関数から戻り値としてvoidポインタを受け取り、 それをDLLの別の関数を呼び出す際に引数として渡すプログラムを作成しようとして 詰まっています。以下サンプルです。 ===VB側 Public Type Param   sStr As String   lNum As Long End Type Declare Function Create Lib "test.dll" (ByRef tParam As Param) As Long Declare Function Free Lib "test.dll" (ByVal pSt As Any) As Long Dim pSt As Long Dim lRet As Long Dim tParam As Param With tParam   .sStr = "test" & Chr(0)   .lNum = 10 End With pSt = Conn(tParam) lRet = Free(pSt) ===VC側 typedef struct stParaA {   char * aaa;   char * bbb; } PARAM_A; typedef struct stParaB {   char * ccc;   int iNum; } PARAM_B; extern "C" void * __stdcall Create(PARAM_B* stParaB) {   PARAM_A stParaA;   //stParaAの各メンバ領域をMallocで確保   return((void*)stParaA); } extern "C" int __stdcall Free(void* stParaA) {   //stParaAの各メンバ領域をfree   return 0; //正常終了の場合 } VC側でデバッグしてみたところ、stParaBの各メンバの値はVC側で取得できているので、 DLLの呼び出し自体には問題はないようですが、Create()でreturnする時と、Free()に 入ってきたときではstParaAのアドレスが変わってしまい、異常終了します。 VC側はソースはあるのでデバッグは可能なのですが、DLLの修正自体は不可となって いるため、VB側を直すしかないのですが、どのようにすればアドレスの受け渡しが できるのでしょうか。

  • TextBoxの文字がかけてしまうのですが VB.NET

    VB.NET FrameWork1.1の環境なのですが、 Declare Function WritePrivateProfileString Lib "KERNEL32.DLL" Alias "WritePrivateProfileStringA" ( _ ByVal lpAppName As String, _ ByVal lpKeyName As String, _ ByVal lpString As String, _ ByVal lpFileName As String) As Integer このAPIを使ってファイルに文字列を記録しているのですが、 TextBoxに表示したファイルのフルパスを記録すると このAPIを使った直後にそのTextBoxの文字の後半が欠けてしまいます。 短いパス名なら大丈夫なのですが、長いパス名の場合に欠けてしまいます。 試しに Dim a As String = TextBox1.Text WritePrivateProfileString("TextBox", "1", a, FileName) Console.WriteLine(a) としても同じく欠けてしまいます。 変数aの宣言の型をString ではなく Object にすると 欠けなくなるのですが、変数aやTextBoxの内容は読み取った だけなのになぜ書き換えられてしまうのでしょうか? どの場合でもファイルへの記録は正常に出来ています。 何か問題点などありましたらご教授いただけると助かります。

  • VB2008: 文字列を逆順にする関数が判らない!

    Sub Main()   Debug.Print(Reverse("ABC") End Sub Function Reverse(ByVal aChars As String) As String   Dim C As Char   Dim I As Integer   Dim J As Integer   Dim L As Integer = aChars.Length - 1   J = L   Do While I < J     C = aChars.Chars(I)     aChars.Remove(I, 1)     aChars.Insert(I, aChars.Chars(J))     aChars.Insert(J, C)     aChars.Remove(J + 1, 1)     J -= 1     I += 1   Loop   Return aChars End Function 1、"ABC"の"A"を変数 C に保存。 2、"ABC"の"A"を削除。 3、"BC" の先頭に"C"を挿入。 4、"CBAC" の3番目(J=2)に変数Cを挿入。 5、"CBAC" の4番(J+1=3)を削除 6、"CBA" を戻り値にセット。 という Reverse 関数ですが動作しません。 一体、どこでどのように考え違いをしているのでしょうか? 全くわかりません。 宜しくお願いします。

  • 特殊文字含むdll参照方法

    こんにちは visual studio 2010 vb環境で開発を行なっているのですが 本当は、 Private Declare Function AqKanji2Koe_Create Lib "AqKanji2Koe" _ (ByVal Koe As String, ByVal pint As Integer) As Integer としたいのですが、 これだと、エントリ ポイントが見つかりませんでエラーが出てしまい、 検索したところ、下記情報があり http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1256891532 これになぞって、試しに@8を入れてみたのですが、 Private Declare Function AqKanji2Koe_Create@8 Lib "AqKanji2Koe" _ (ByVal Koe As String, ByVal pint As Integer) As Integer @は使えないとエラーが出てしまいます。 何か対応する方法はありますでしょうか?

  • VB2003で レジストリを格納する

    レジストリを格納するために、以下のように宣言し、 Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Integer, ByVal lpSubKey As String, ByVal Reserved As Integer, ByVal lpClass As String, ByVal dwOptions As Integer, ByVal samDesired As Integer, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByRef phkResult As Integer, ByRef lpdwDisposition As Integer) As Integer Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Integer, ByVal lpValueName As String, ByVal Reserved As Integer, ByVal dwType As Integer, ByRef lpData As String, ByVal cbData As Integer) As Integer Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Integer) As Integer 以下のようなコードで、ユーザーエージェントをmozillaからoperaへ(またはoperaからmozilla)書き換えようとしていますが、うまくいきません。 問題点1.同じuser agentの下に”(既定)”が2つできてしまう 問題点2.データが正しく(operaと)書き込まれず、文字化けしたものが書き込まれている。 C言語用のサンプルやVB6.0のサンプルは見ますが、VB2003ではどのように指定するのか、わかりませんでした。 Dim ret As Long Dim hKey As Long, lngDisposition As Long Dim udt As SECURITY_ATTRIBUTES Dim myroot_key As String, mysub_key_user_agent As String, myName As String,StrValue As String myroot_key = &H80000002 '"HKEY_LOCAL_MACHINE" を指定している mysub_key_user_agent ="Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent" myName = "(既定)" strValue="Opera" ret = RegCreateKeyEx(myroot_key, mysub_key_user_agent, 0&, vbNullString, _ 0, &H4 Or &H2, udt, hKey, lngDisposition) If ret = 0 Then ret = RegSetValueEx(hKey, myName, 0, 1, strValue, Len(strValue) + 1) RegCloseKey(hKey)

専門家に質問してみよう