4

簡単な質問があります。vb.netは文字列の長さをどのように決定し、文字列の終了を処理しますか?
私はC(そしてそのファミリーで)ヌル文字が文字列の終わりであることを知っています。vb6ではヌル文字は文字列の終了に影響を与えませんが、vb.netでは霧のようです!
vb6でこのコードを想定します。

Private Sub Command1_Click()
Dim Str As String
Str = "Death is a good user," & Chr(0) & " Yes I'm good"
RichTextBox1.Text = Str
RichTextBox1.Text = RichTextBox1.Text & vbNewLine & Len(Str)
End Sub

これは、このコードが実行されたときに何が起こるかです。 ここに画像の説明を入力してください

そして、それは大丈夫です。これは次のようなコードですC

#include "stdafx.h"
#include <string.h> 
int main(int argc, char* argv[])
{
    char *p="Death is a good user,\0 Yes I'm good";

    printf("String:%s\nString length:%d\n",p,strlen(p));

    return 0;
}

そして、これが起こることです:
ここに画像の説明を入力してください

これもCルールに従っては問題ありませんが、vb.netの同じコードは次のとおりです。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim str As String = "Death is a good user," & Chr(0) & " Yes I'm good"
    RichTextBox1.Text = str
    RichTextBox1.Text &= vbNewLine & str.Length
End Sub

そして何が起こるか:
ここに画像の説明を入力してください


これは正しくないようです!

編集1:ファイルへの書き込みは正しいようです:

ここに画像の説明を入力してください

編集2Marktcarvinが示唆しているように、UIの問題かもしれませんが、vb6が文字列全体を表示する理由は説明されていません。

編集3:WindowsとそのAPI、UI、...がで書かれていることを知っているので、C彼らがのように反応するのは正常ですCが、上で示したように、そうではありません。

4

2 に答える 2

9

VB.NET(およびC#)では、文字列はVB6の場合と非常によく似て扱われます。つまり、文字列は、特定の1つまたは複数の文字に含まれない明示的な長さを持ちます。

RichTextBoxに関しては、埋め込まれたnull文字をサポートしていないように見えます。

于 2012-11-27T22:27:37.853 に答える
3

基盤となるランタイムサポートライブラリによってスニペットで使用される3つの異なる文字列タイプがあります。

  • BSTR、VB6で使用されます。これは、Unicode文字列を格納でき、明示的な長さを含むすべてのActiveXコントロールで使用されるCOMオートメーションタイプです。したがって、BSTRは埋め込みゼロを格納できます。
  • C言語で使用されるC文字列。明示的な長さは格納されません。ゼロは文字列の終わりを示します。winapiはCベースであり、関数でC文字列を使用します。
  • System.String、.NET文字列型であり、任意の.NETコードで使用されます。BSTRと同様に、明示的な長さフィールドもあるため、ゼロが埋め込まれた文字列を格納できます。

3つのケースすべてで、文字列を表示するには、基盤となるランタイムサポートライブラリで相互運用機能を使用する必要があります。

  • VB6は、RichEditBoxにActiveXコントロールを使用します。コントロールがどのように見えるかを正確に推測するのは難しいです。それはVB6にかなり固有であり、richtx32.ocxという名前です。ネイティブのWindowsリッチエディットコントロール(riched32.dll)も使用するため、ActiveXコントロールは、ネイティブのWindowsコントロールをVB6アプリで使用できるようにするラッパーとして非常に機能します。これは、ActiveXコントロールと同様に、BSTRの動作を尊重し、埋め込まれたゼロを処理することを最終的に示しました。

  • CプログラムはCランタイムライブラリを使用し、Cランタイムライブラリはwinapiコンソール関数WriteConsole()を呼び出すことによってprintf()を実装します。このAPI関数はCベースですが、バックはすでにprintf()で停止しており、埋め込まれたゼロはその関数の文字列ターミネーターです。ここに驚きはありません。

  • Winformsプログラムは、riched20.dllネイティブWindowsコントロールのマネージラッパーである.NETRichEditBoxクラスを使用します。基盤となるメカニズムはpinvokeであり、クラスのほとんどすべてのプロパティとメソッドは、SendMessage()をピンボーキングして、コントロールによって表示されるテキストを変更するメッセージであるEM_SETTEXTEXなどのメッセージを送信することによって実装されます。これもCベースのAPIであり、ゼロは文字列ターミネータのように機能します。richtx32.ocxラッパーとは異なり、.NET RichEditBoxラッパークラスは、ゼロが埋め込まれた文字列を適切に処理するための努力をしません。文字列をそのまま渡し、pinvokeマーシャラーに任せて.NET文字列をC文字列に変換します。C文字列には長さフィールドがないため、これは文字列をゼロで切り捨てる以外に選択肢はありません。

于 2012-12-06T23:36:33.773 に答える