DOBON.NETプログラミング道掲示板

No34104 の記事


■34104 / )  Re[5]: 参照dllへの文字列引数をutf8で渡したい。
□投稿者/ 魔界の仮面弁士 大御所(1191回)-(2019/01/17(Thu) 12:42:37)
  • アイコンNo34103に返信(ukotsさんの記事)
    > UTF8のバッファーをUnicodeにEncodingして、末尾の0hを消去して実用に供する予定です。

    あれ? lstrlenA は「0h の直前までのバイト数」を返すので、
    取得したバッファー内に 0h が含まれることは無いはずなのですが…。

    たとえば UTF-8 文字列のバイナリ表現が
     { &HE5, &HBC, &H81, &HE5, &HA3, &HAB,  &H0  , &HCE, &HB2 }
    だったとしたら、戻り値は 7 では なく 6 ですし、
     { &H0  , &HE5, &HBC, &H81, &HE5, &HA3, &HAB, HCE, &HB2 }
    だった場合、戻り値は 1 ではなく 0 となります。


    もしかして、
    > (3) 受信バッファとして、その長さの Byte 型 1 次元配列を確保する
    > (4) 確保したバッファに、Marshal.Copy( IntPtr, Byte(), Integer, Integer) メソッドで複写
    の手順で、サイズ指定をミスっていたりはしませんか?


    > PS: NLPIR_FileProcess(FileName,FileName,1) As Doubleについては、

    この API ですよね。第 3 引数は Optional ByVal bPOStagged As Integer = 1 かな。

    Double NLPIR_FileProcess(
     const char *sSourceFilename,
     const char *sResultFilename,
     int bPOStagged = 1);


    この場合の入力引数も、先の戻り値と同様、「Encoding.UTF8 を使って自前で変換する」だけです。

    現状の引数宣言が、
     <MarshalAs(UnmanagedType.LPStr)> ByVal sSourceFilename As String
    になっているのだとしたら、それを
     ByVal sSourceFilename As Byte()
    もしくは
     ByVal sSourceFilename As IntPtr
    にしてみてください。


    As Byte() で渡す場合は、 No34093 で Hongliang さんが書かれたコードそのままです。
     Dim bytes As Byte() = Encoding.UTF8.GetBytes("Source.txt" & vbNullChar)


    As IntPtr で渡す場合は、
     Dim ptrSrc As IntPtr = Marshal.StringToHGlobalUTF8( "Source.txt" & vbNullChar )
     Dim ptrDst As IntPtr = Marshal.StringToHGlobalUTF8( "Result.txt" & vbNullChar )
     Dim ret As Double = NLPIR_FileProcess( ptrSrc, ptrDst, 1 )
     Marshal.FreeHGlobal( ptrDst )
     Marshal.FreeHGlobal( ptrSrc )
    としたいところですが……残念ながら StringToHGlobalUTF8 なんていうメソッドは無いので、こんな感じで。
     Dim bytes As Byte() = Encoding.UTF8.GetBytes("Source.txt" & vbNullChar)
     Dim ptrSrc As IntPtr = Marshal.AllocHGlobal( bytes.Length )
     Marshal.Copy(bytes, 0, ptrSrc, bytes.Length)
     Dim ptrDst As IntPtr
     '中略:ptrDst も ptrSrc と同様の手順で、AllocHGlobal + Copy で UTF-8 バッファを作成
     Dim ret As Double = NLPIR_FileProcess( ptrSrc, ptrDst, 1 )
     Marshal.FreeHGlobal( ptrDst )
     Marshal.FreeHGlobal( ptrSrc )
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -