C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.8907 の関連記事表示

<< 0 >>
■8907  GetPrivateProfileStringにつきまして
□投稿者/ ことぶき -(2007/10/12(Fri) 22:47:57)

    分類:[VB6 以前] 

    はじめまして。
    visual stadio6.0を使用しています。
    vb6.0に関しての質問です。

    ネイティブはjavaなのですがこの度、vbをさわる機会に恵まれました。
    既存のソースを眺めていて疑問が湧き、自分では解決に至りませんでしたので、
    申し訳ありませんが力を貸してください。

    ソースにGetPrivateProfileStringを使うものがありました。
    その第四引数に指定したstringの変数にiniファイルの該当部分が格納されているようです。

    ********************************ソースイメージ(環境が無いので検証はできていません)***********
    Dim hoge as string * 1024
    Dim piyo as long
    Dim bar = string
    piyo = GetPrivateProfileString("キー","セクション","",hoge,(length),(iniファイル名))
    bar = hoge
    ******************************************************************************************

    しかし、呼び出し先のGetPrivateProfileString()メソッドの第四引数はbyValが指定されています。
    #これは値渡しの指定ですよね?
    また、vb6.0ではstringはオブジェクト型ではないとの記述をwebで見ました。
    その為、アドレスを引数に渡しwinAPI側でアドレスの参照先を変更しているのではないと思っています。

    しかし、私の意に反して多くの(私が見た)解説ページでは当然のことのように説明が省かれています。

    何故、上記変数barにiniファイルの値が入るのでしょうか?

    #質問自体にいたらない点などありましたらお詫び申し上げます。
親記事 /過去ログ21より / 関連記事表示
削除チェック/

■8921  Re[1]: GetPrivateProfileStringにつきまして
□投稿者/ Starfish -(2007/10/13(Sat) 16:30:41)
    No8907 (ことぶき さん) に返信
    > しかし、呼び出し先のGetPrivateProfileString()メソッドの第四引数はbyValが指定されています。
    > #これは値渡しの指定ですよね?
    > また、vb6.0ではstringはオブジェクト型ではないとの記述をwebで見ました。
    > その為、アドレスを引数に渡しwinAPI側でアドレスの参照先を変更しているのではないと思っています。
    > 
    > しかし、私の意に反して多くの(私が見た)解説ページでは当然のことのように説明が省かれています。
    
     Windows API の関数を呼ぶ時は、文字列は値渡しで行います。詳しくは、ヘルプを
    参照してください。
    
    Visual Studio 6.0 ドキュメント
    + Visual Basic ドキュメント
     + Visual Basic の使用方法
      + コンポーネント ツール ガイド
       + DLL および Windows API へのアクセス
        + DLL プロシージャへの文字列の引き渡し
記事No.8907 のレス /過去ログ21より / 関連記事表示
削除チェック/

■8934  Re[1]: GetPrivateProfileStringにつきまして
□投稿者/ ぶっちゃん -(2007/10/14(Sun) 15:30:48)
    No8907 (ことぶき さん) に返信

    > 何故、上記変数barにiniファイルの値が入るのでしょうか?
    え?
    > bar = hoge
    ってやってるからじゃないの?
記事No.8907 のレス /過去ログ21より / 関連記事表示
削除チェック/

■8941  Re[2]: GetPrivateProfileStringにつきまして
□投稿者/ ことぶき -(2007/10/15(Mon) 00:06:37)
    Starfishさん、ぶっちゃんさんレスありがとうございます。

    >Starfishさん
    > Windows API の関数を呼ぶ時は、文字列は値渡しで行います。詳しくは、ヘルプを
    >参照してください。

    ***************ことぶきの書き込み********************

    しかし、呼び出し先のGetPrivateProfileString()メソッドの第四引数はbyValが指定されています。
    #これは値渡しの指定ですよね?
    また、vb6.0ではstringはオブジェクト型ではないとの記述をwebで見ました。
    その為、アドレスを引数に渡しwinAPI側でアドレスの参照先を変更しているのではないと思っています。

    ****************************************************

    にあるとおり値渡しであることは分かりました。
    分からないのは「これは参照渡しの挙動では?なんでhogeの値が変わるの?」ということです。
    ヘルプに関するご指摘ありがとうございます。
    明日(今日?)早速調べてみます。(何を調べてよいかも分からない状態でした。)

    >ぶっちゃんさん
    >> 何故、上記変数barにiniファイルの値が入るのでしょうか?
    >え?
    >> bar = hoge
    >ってやってるからじゃないの?

    おそらくそうなのでしょうが、私には理由が分かりませんでした。
    hoge(上記ソースイメージには書き忘れてしまいましたが初期化をしただけの変数です。)
    はどの段階で書き換えられているのですか?
    vb6では当然の挙動なのかもしれませんが値渡しで渡した引数が書き換えられて戻ってくる(≠戻り値)事に
    相当違和感を感じています。

    「この情報がないとわからない。」
    など私が書き忘れていることがございましたら併せてご指摘ください。
    宜しくお願いいたします。
記事No.8907 のレス /過去ログ21より / 関連記事表示
削除チェック/

■8942  Re[3]: GetPrivateProfileStringにつきまして
□投稿者/ Starfish -(2007/10/15(Mon) 01:34:35)
    No8941 (ことぶき さん) に返信
    > にあるとおり値渡しであることは分かりました。
    > 分からないのは「これは参照渡しの挙動では?なんでhogeの値が変わるの?」ということです。
    > ヘルプに関するご指摘ありがとうございます。
    > 明日(今日?)早速調べてみます。(何を調べてよいかも分からない状態でした。)

     VBの文字列はUNICODEですがWindowsではANSIです。(UNICODEのインターフェースもありますが
    VBから使うときは一般的にはANSIのものを使います。)

     なので、動作的には、値渡しでも参照渡しでもありません。Byval をつけるのは、深く考えずに
    そういう決まりだと考えたほうがいいと思います。

    > bar = hoge

     これでは、hogeの1024文字分のデータがコピーされるので、barには後ろにごみのデータが
    ついています。ヘルプにも記載されていますが以下のようにしてNULL以降のデータを削除する
    必要があります。

    bar = Left(hoge, InStr(hoge, Chr$(0))-1)
記事No.8907 のレス /過去ログ21より / 関連記事表示
削除チェック/

■8943  Re[3]: GetPrivateProfileStringにつきまして
□投稿者/ 魔界の仮面弁士 -(2007/10/15(Mon) 05:08:37)
    No8941 (ことぶき さん) に返信
    > vb6では当然の挙動なのかもしれませんが値渡しで渡した引数が書き換えられて戻ってくる(≠戻り値)事に
    > 相当違和感を感じています。
    確かに通常は、「値渡し」で内容が書き変わる事は無いのですが、Declare ステートメントを
    使っている場合は、API 側でそのポインタの示す文字列の内容を編集する事ができるのです。
    
    これは、文字列型変数が『文字列へのポインタ』として管理されているという事情によるものです。
    (BSTR は、OLE ヘッダ ファイルでは OLECHAR FAR * として定義されます)
    
    なお、Declare にて、文字列を参照渡しするのは、(LPSTRではなく)BSTRを受け取る場合だけです。
    
    ついでに書いておくと、Declare では、文字列の ANSI/Unicode 変換も同時に行われるため、
    文字列型では LPWSTR を受け取ることが出来ません。そのため、Unicode 文字列を渡す場合は、
    バイト配列を使って渡すのが慣例となっています。(または、アドレスを値渡しする方法もあり)
    
    
    より細かい内容について知りたいのであれば、MSDN ライブラリの
    [MSDN ライブラリ 2001 年 4 月]
    └[技術情報]
     └[技術情報 (日本語)]
      └[ビジュアル ツール]
       └[Visual Basic]
        └[Visual Basic]
         └[Microsoft Visual Basic Version 5.0 で使用する DLL の開発に関する注意]
    を参照してみてください。
    
    
    
    
    以下、No8921で紹介されている内容に絡めた、String 型に関する実験コード。
    
    変数のアドレスを取得する「VarPtr 関数」と、
    文字列のアドレスを取得する「StrPtr 関数」を使っています。
    
    '----------------------
    Option Explicit
    
    Private Declare Sub RtlMoveMemory Lib "KERNEL32" _
       (ByRef hpvDest As Any, _
        ByVal hpvSource As Long, _
        ByVal cbCopy As Long)
    
    Private Sub Command1_Click()
        Dim S As String, bin() As Byte
        S = Text1.Text
        bin = S
    
        Debug.Print "============="
        Debug.Print "変数Sの文字列の長さ:="; Len(S); "(文字数)"
        Debug.Print "変数Sの内容:=「"; S; "」"
        Debug.Print "変数Sのバイナリ:=「"; DumpStr(bin); "」"
    
        Dim pVar As Long, pStr As Long
        pVar = VarPtr(S)
        pStr = StrPtr(S)
    
        Debug.Print "============="
        Debug.Print "VarPtr(S):="; Hex(pVar); ":変数S のアドレス"
        Debug.Print "StrPtr(S):="; Hex(pStr); ":文字列のアドレス"
    
        Dim pVarValue As Long, size As Long
        pVarValue = ReadLong(pVar)
        size = ReadLong(pStr - 4)
    
        Debug.Print "============="
        Debug.Print Hex(pVarValue)
        Debug.Print "  = ReadLong(VarPtr(S))"
        Debug.Print "  これは、StrPtr(S) と一致する"
        Debug.Print "  文字列変数の場合、VarPtrはStrPtrへのポインタを指す"
        Debug.Print CStr(size)
        Debug.Print "  = ReadLong(StrPtr(S) - 4)"
        Debug.Print "  これは、文字数の2倍と一致する"
        Debug.Print "  StrPtrの直前4バイトには、文字列のバイト数が格納されている"
        Debug.Print Dump(pStr, size)
        Debug.Print "  = Dump(pStr, バイト数)"
        Debug.Print "  これは変数 S のバイナリと一致する"
        Debug.Print "  StrPtrからのアドレスには、文字列本体が格納されている"
    End Sub
    
    Private Function ReadLong(ByVal Ptr As Long) As Long
        RtlMoveMemory ReadLong, Ptr, 4
    End Function
    
    Private Function Dump(ByVal Ptr As Long, ByVal Length As Long) As String
        Dim n As Long, b() As Byte
        If Length > 0 Then
            ReDim b(Length - 1)
            RtlMoveMemory b(0), Ptr, Length
            For n = 0 To Length - 1
                Dump = Dump & Right("00" & Hex(b(n)), 2) & " "
            Next
        End If
    End Function
    
    Private Function DumpStr(ByRef bin() As Byte) As String
        Dim v As Variant
        For Each v In bin
            DumpStr = DumpStr & Right("00" & Hex(v), 2) & " "
        Next
    End Function
    
    Private Sub Form_Load()
        Text1.Text = "あいうえお"
    End Sub
記事No.8907 のレス /過去ログ21より / 関連記事表示
削除チェック/

■8982  Re[4]: GetPrivateProfileStringにつきまして
□投稿者/ ことぶき -(2007/10/15(Mon) 21:28:07)
    Starfishさん、魔界の仮面弁士さんレスありがとうございます。
    また、レス/お礼が遅くなり申し訳ありません。

    >Starfishさん
    >なので、動作的には、値渡しでも参照渡しでもありません。Byval をつけるのは、深く考えずに
    そういう決まりだと考えたほうがいいと思います。

    私も最初はそう考え、作業を進めていたのですがどうしても気になってしまい、
    今回質問するに至りました。

    >魔界の仮面弁士さん
    「Microsoft Visual Basic Version 5.0 で使用する DLL の開発に関する注意」
    はググって見つけることが出来ました。

    疑問に思っていた事にお答えいただきありがとうございます。
    とてもすっきりしました。

    また、実験コードのご提示までしていただきありがとうございます。
    何をするコードなのかしっかり理解した上で実行してみたいと思います。

    >お付き合いいただいた方々
    皆さんのおかげで疑問を解消する事が出来ました。ありがとうございます。
記事No.8907 のレス / END /過去ログ21より / 関連記事表示
削除チェック/

■8983  Re[5]: GetPrivateProfileStringにつきまして
□投稿者/ 魔界の仮面弁士 -(2007/10/15(Mon) 21:38:42)
    一応補足。

    No8982 (ことぶき さん) に返信
    > >魔界の仮面弁士さん
    > 「Microsoft Visual Basic Version 5.0 で使用する DLL の開発に関する注意」
    > はググって見つけることが出来ました。

    オンライン版だと、このあたりですね。
    http://www.microsoft.com/japan/msdn/vs_previous/vbasic/docs/dll/
記事No.8907 のレス / END /過去ログ21より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -