精华内容
下载资源
问答
  • 转载:VB中String的用法及原理2008-05-07 09:02 转自:http://dev.csdn.net/article/83943.shtm在各种不同开发语言中,字符串类型显然是最常见,也是最常用的。 常用代表它最易用,是这样吗?未必,越简单,越普通,...
    转载:VB中String的用法及原理
    2008-05-07 09:02

     

    转自:http://dev.csdn.net/article/83943.shtm

    在各种不同开发语言中,字符串类型显然是最常见,也是最常用的。
        常用代表它最易用,是这样吗?未必,越简单,越普通,你会忽视,内里隐藏着的陷井更容易使你中招。它往往是绊脚石,或者程序中性能的瓶颈。
        本身,我对VB语言及相关应用并不太熟,只不过近期编码用到,有些体会。

    一: 先来总结一下,常用编程语言的字串表达方式:
    C:      char(wchat_t) * 或 []:   字符数组来表示字符串,以0结尾,无长度标识。
              配一堆操作函数,不好记,不好用。
    C++:   std::string   basic_string<>的特化版本. 注意:其内在的数据区由默认的内存管理器分配。
             对象哈,提供还算好用的方法。
    MFC: CString 标准的C++类. 数据项:LPTSTR 一堆可用的方法。
    Windows普通API DLL:        LPTSTR 采用C标准的0结束字串
    Windows扩展COM中:          BSTR   OLE标准, 头上带长度标识的字符串.
    Java中:                             java.lang.string
    VB中:                               String    实际上就是OLE标准的BSTR
    好了,我们关心的是BSTR。
    看看BSTR到底是什么东东。
    1.0:看看在Windows SDK中的定义:
    typedef OLECHAR* BSTR;
    typedef WCHAR OLECHAR;
    typedef wchar_t WCHAR;
    所以,它实际上是宽字符指针。

    1.1:它的内存结构呢?很容易查到资料。
    前置四字节,内置字串的长度,后面是字串内容,原则上并不以'/0'结尾,长度由前置值决定。
    所以,它又不简简单单就是宽字符指针。但从基本类型定义上来看,它与宽字符指针是可以划等号的。

    1.2:那VB中的String也就明白了。实际上是地址,是字串的首地址(注意:不是长度的首地址)
    另外,String是可以装载中间带'/0'字符的字串的,只不过,一些显示函数可能将其省略。
    如:dim str as string
         str = "ab" & chr(0) & "cd"
         MsgBox str   '输出:ab
         Debug.Print str '输出 ab cd

    1.3:可以看出,它很特珠,Windows提供几个函数,用来分配和释放它。
    分配:SysAllocStringLen      SysAllocString
    释放:SysFreeString
    取长度:SysStringLen
    注意:分配得到的BSTR,实际上仍然是以'/0'结尾。SysStringLen似乎有点儿英雄无用武之地,呵。
    比如:SysAllocStringLen 的说明文档:
    Allocates a new string, copies cch characters from the passed string into it, and then appends a null character.
    比如:SysAllocString,我们可以通过例子:
    BSTR bstrVal = ::SysAllocString(L"abcd");
    for(int n=0;n<::SysStringLen(bstrVal)+1;n++)
    {
       TRACE(_T("/n%d"),*(bstrVal+n));
    }
    ::SysFreeString(bstrVal);
    输出:
    97
    98
    99
    100
    0
    仍然有0。

    1.4:VC中的用法:
    无论用MFC,还是ATL,实际上,由于BSTR并不是基本类型,而它的相关操作函数也是沿用的以'/0'结尾的函数,所以,虽然它在字串中可以带'/0',但实际上,经过相关操作后,'/0'后的内容会丢掉,这要小心。比如,我们看看CString的构造:
    CString::CString(LPCWSTR lpsz)
    {
    Init();
    int nSrcLen = lpsz != NULL ? wcslen(lpsz) : 0;
    if (nSrcLen != 0)
    {
       AllocBuffer(nSrcLen*2);
       _wcstombsz(m_pchData, lpsz, (nSrcLen*2)+1);
       ReleaseBuffer();
    }
    }

    小结:BSTR有长度标识,但是MS在实现时,为了兼容以前的字串操作,再加上BSTR并不是基本类型,所以,它的分配函数和一些操作函数都是把它当作'/0'结尾来处理。千万要注意。最好也不要用它来装载中间带'/0'的字串,因为,说不定什么时候,它就丢掉了。

    二:   VBr的应用中将麻烦的地方,应该集中在以下几个方面:
    2.1: VB调用Windows API DLL

    2.1.1: 字串作为输入参数
       这还用说吗?
       在API中如果是LPTSTR,在VB中直接转为Byval s as String
       原因?   为什么 BSTR可以直接转为 LPTSTR ?
       前面其实已经讲了,再说一次吧。
       BSTR实际上是指针,指向字串头.所以,采用ByVal指向的刚好是字串的首地址,也就是LPSTR,嘿嘿,刚刚好,符合需要,真是巧啊。

    2.1.2: 字串作为输出参数
    这个麻烦一点,举个例子吧.
    如:
         UINT GetWindowsDirectory(
           LPTSTR lpBuffer,
           UINT uSize
        );
    使用API Viewer得到声明
        Public Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" _
           (ByVal lpBuffer As String, ByVal nSize As Long) As Long
    代码:
         Dim sTemp As String * MAX_PATH
         Dim lsize As Long
         Dim str As String
         lsize = GetWindowsDirectory(sTemp, MAX_PATH)
         str = Left(sTemp, lsize)
         MsgBox "Windows路径:" & str & "长度:" & Len(str)
    注意一下:
    A: 引用的Windows API是A版,而不是W版,如果是W版会有错误.
    原因,我的猜测是:    VB的API调用机制中,字串强制做了UNICODE到ANSI的转换.API的DLL没法告知调
    用端,它是Unicode版还是ANSI版.如果是OCX或COM就没问题了,因为它们有标识。没办法,只能用一种了, MS选了A版。
    B: 参数是ByVal
    道理同作为输入时,实际上传的指针,所以,指向的内容是可以修改地,也就可以返回了。
    C: 根据API的使用说明,可得到
    [out] Pointer to the buffer to receive the null-terminated string containing the path.
    需要调用方分配空间,因此, sTemp需要给足够长度的空间.
    D: 返回的0结尾的字串,可以用left达到目的.
    因为:VB的String对应的是BSTR类型,长度由前置字节决定,而不是0字符决定.

    2.1.3: 字串作为Return值
    这种API是不是存在呢?系统级的没看见,一般不会这样用,因为这存在内存分配的问题.
    但我自已好像写过,处理方式是:
    VB声明中可以使用long返回,然后用lstrcpy进行转换,
    说起lStrCpy就不得不说说它的作用了,它实在是很关键,它很神奇,它可以把
    地址指向的字符串拿出来。
    我们来看看原理:
    lStrcpy本身只是简单的复制字符串的函数:
    Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long 如果按照API View中的声明,是不行的.它确实就是字串拷字串,没办法把字址指向的字串拷到另一串.
       好了,需要小小改动一下:
       首先:目的地没错,确实应该是指向字串的首地址.用Byval String就可以.第一个参数OK。
       源串呢? 因为你传入的实际上不是String,而是long啊(上例返回的是long噢),那当然应该将声明改成long,否则,传入的String会变成啥,啥都不是呢?就这么简单。

    2.1.4: LPTSTR 都可以用VB的byval String替代吗?
    如果在结构体里,可就不是这样了.
    如:EnumForms   枚举某个打印机的所有打印纸型。
    Public Declare Function EnumForms Lib "winspool.drv" Alias "EnumFormsA" (ByVal hPrinter As Long, _ ByVal Level As Long, ByRef pForm As FORM_INFO_1, ByVal cbBuf As Long, ByRef pcbNeeded As Long, _
    ByRef pcReturned As Long) As Long
    对于 FORM_INFO_1的定义:
    Public Type FORM_INFO_1
             Flags As Long
             pName As String
             Size As SIZEL
             ImageableArea As RECTL
    End Type
        如果按上述的方法调用,会出现异常.估计是在拷贝数据时,String实际上是不同于LPTSTR的,因为它的前面还有四字节是标识长度的,如果定义为String,那在构造pName之前的长度,必将动到它不应该动到的地方,这样,就错了.想来不会异常退出的,但却退出了,不知原因(我没弄明白)

    所以,此种情况,应该将pName变为long,然后再用2.1.3提到的方法,将字串拷贝出来使用.
              这样,就OK了。

    引申一下:
        对于一些API中大的结构体中的指针类型,我们完全可以用long来取代它,然后传递0&,因为,大多数情况,我们是不需要传入任何参数的,避免定义很多我们并不需要的类型.这样就降低了API使用的复杂性。

    2.2 : VB调用COM组件(或OCX控件)
    这似乎没啥可说的,COM组件的接口一般都是标准的BSTR,与VB的String完全兼容.
    VB调用端没啥问题,倒是书写COM的程序需要注意:
    2.2.1: 应用端可能会传入空指针.比如传入vbNullString,这需要留意.
    2.2.2: BSTR的释放与普通LPTSTR可不同,使用前需要初始化,使用后要释放,当然,VB无此烦恼.

    3: VB字串的连接操作.
        当我们要序列化生成文本文件时,大都喜欢先将内容写入字串,然后再一次写了文件.否则多次写入文件,似乎有效率低之嫌,但如果字串为多次累加而成,那么使用VB字串的连接操作,将是效率极差的做法,这也变成性能低下的重要原因.
        分析一下原因:
        对于String的连接,系统的做法一定是重分配空间,搬移到新空间,拷贝进新内容.如果连接次数较多,且较细,那将是灾难性的。(类似MFC的CString的做法,假设我们要写一个100K长度的字串,但每次添加一个字符,那你可以试试它的速度)
       如何解决?
        很简单,采用预分配内存块, 当内存块不够用时,自动增加指定块的增量(当然每次增长的内存块这个阀值需要慎重考虑)
        这样,减少搬移操作,效率自然提升。
        具体实现:可以使用内存操作API实现.VB会麻烦一点(需要用API生成全局内存,自行完成搬移,拷贝),
    VC可以直接使用CMemFile简单搞定.

    4: VB字串多语言化
    4.1: 一般的做法是: 将原生串与多语言串做成Key.Value Pair结构。多语言信息为Value,然后做一个简单的Hashc ode来索引,或者干脆用Hash Map来实现 (为了更高效,更容易使用已有容器,最好借助于C++编写相关支持)。
    4.2: 为了使UI上的字串也能多语言化,需要保证字串信息为动态加载。
    4.3: 对于控件的字体编码字符集也需要处理,以保证正确显示。

    展开全文
  • vb.net 中string 类型如何转换成 TimeSpan

    千次阅读 2018-10-09 09:36:20
    vb.net 中string 类型如何转换成 TimeSpan 可以使用timespan的赋初值功能实现: Private Function StringConvertTimeSpan(ByVal _D As String, ByVal _H As String, ByVal _M As String, ByVal _S As String) As ...

    vb.net 中string 类型如何转换成 TimeSpan

    可以使用timespan的赋初值功能实现:

        Private Function StringConvertTimeSpan(ByVal _D As String, ByVal _H As String, ByVal _M As String, ByVal _S As String) As TimeSpan
            Dim tempTimeSpan As TimeSpan = New TimeSpan(Convert.ToInt32(_D), Convert.ToInt32(_H), Convert.ToInt32(_M), Convert.ToInt32(_S))
            Return tempTimeSpan
        End Function
    
    

    参数_D,_H,_M,_S分别代表天,小时,分钟和秒的字符串。
    直接带实参调用此函数就可以了。

    展开全文
  • VB中String类型调用VC的DLL

    千次阅读 2012-10-30 10:55:40
    VB中String类型调用VC的DLL EXTERN_C BSTR WINAPI RetStr(LPCTSTR str)  {  return SysAllocString((BSTR)str);  }  VB中 Private Declare Function RetStr Lib "D:\learn\VB\fangda\MFCDIB....

    VB中的String类型调用VC的DLL

    EXTERN_C BSTR WINAPI RetStr(LPCTSTR str) 


    return SysAllocString((BSTR)str); 

    VB中

    Private Declare Function RetStr Lib "D:\learn\VB\fangda\MFCDIB.dll" (ByVal send

    As String) As String

    Dim result As String
    Dim str As String
    str = "12345"

    result = RetStr(str)
    MsgBox result

    -----------------------------------------------------------------------------
    第二个程序
    VC++
    EXTERN_C BSTR WINAPI add(LPSTR a,LPSTR b)

             strcat(a,b);
    return SysAllocString((BSTR)a); 
    }
    VB
    Private Declare Function add Lib "D:\learn\VB\fangda\MFCDIB.dll" (ByVal p As

    String, ByVal p As String) As String
    Dim s As String

        s = "Hello"
        Dim k As String
        k = "heihei"
        Dim result As String
        result = add(s, k)
        Debug.Print result
    终于搞定了,整整一天呀!!!!!其实主要是这个函数SysAllocString((BSTR)字符串);因为VB和VC的编码是不同的!

    找到的VB和VC编码的区别:首先就是在VB中声明传递的字符串参数的时候,按照常规的理解,好像应该是传递地址才对,但是这里使用的方法是ByVal,为什么?原因比较复杂,但是可以简单的来分析一下,在VB中,使用的字符串实际上是BSTR类型的,它是由自动化(以前被称为OLE Automation)定义的数据类型。一个BSTR由头部和字符串组成,头部包含了字符串的长度信息,字符串中可以包含嵌入的null值。大部分的BSTR是 Unicode的,即每个字符需要两个字节。BSTR通常以两字节的两个null字符结束。下图表示 了一个BSTR类型的字符串。

      (前缀)aTest\0
      头部BSTR指向数据的第一个字节

      另一方面,大部分的DLL过程(包括Windows 95 API中的所有过程)使用LPSTR类型字符串,这是指向标准的以null结束的C语言字符串的指针,它也被称为ASCIIZ字符串。LPSTR 没有前缀。下图显示了一个指向ASCIIZ字符串的LPSTR。

      aTest\0

      LPSTR指向一个以null结尾的字符串数据的第一个字节

        通过上面的简单分析,不难看出,如果均以地址的方式传递参数的话,那么VB中的字符串将会包含更多德内容,所以,在这里,就必须以值的方式传递参数,虽然是以值得方式传递的参数,但是在DLL中还是能够识别得出来这是一个字符串,并且将它转换成为字符串。

        好了,上面的这个问题我们已经解决了,但是,我们现在的胃口肯定也变得慢慢得有点大了,既然我们已经实现了能够从VB中把字符串传给DLL,那么,又应该怎么样才能够从DLL中把字符串返回给VB程序呢?通过上面的分析我们知道,因为两者之间使用的字符不是相同的格式的,所以简单的传输肯定是不行的,那么应该如何解决呢?其实,在明白了上面我们分析的道理后,再来解决这个问题就太easy了,只需要把传回的字符串进行一次转换就可以了

    展开全文
  • vb.netimage转string

    2016-03-05 23:59:14
    项目需要把手写板的签名图片信息存放到xml文件,要用到image和string类型之间的相互转换,具体实现如下: ''' ''' image类型到string类型的转换 ''' ''' ''' ''' Public Function Pic2String(ByVal ...

    项目中需要把手写板的签名图片信息存放到xml文件中,要用到image和string类型之间的相互转换,具体实现如下:

     ''' <summary>
        ''' image类型到string类型的转换
        ''' </summary>
        ''' <param name="img"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function Pic2String(ByVal img As Image) As String
            Dim ms As New MemoryStream()
            img.Save(ms, Imaging.ImageFormat.Jpeg)
            Dim b() As Byte
            b = ms.GetBuffer
            Dim returnPic As String
            returnPic = Convert.ToBase64String(b)
            ms.Close()
            Return returnPic
        End Function
        ''' <summary>
        ''' string类型到image类型转换
        ''' </summary>
        ''' <param name="strPic"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function getPicFromString(ByVal strPic As String) As Image
            Dim pic As Image
            Dim b() As Byte
            b = Convert.FromBase64String(strPic)
            Dim ms As New MemoryStream(b)
            pic = Image.FromStream(ms)
            ms.Close()
            Return pic
        End Function


    展开全文
  • 今天碰到一个问题,登陆的时候,如果不需要验证手机号为空,则... ... Dim CheckUserInfo() As String ={UserBirthday, SecEmail, UserMob,UserSex, RealNameFirst, RealName, CheckCardID, CheckCardType, Contactema...
  •  在VB.NET,一个字符串可包含大约2亿(2的31次方)个Unicode字符,字符的机内码从0到65535,前128个字符代表英文字母及标准键盘上的字符,128到255个字符代表特殊的字符,如拉丁字母、货币符号、分数等。...
  • VB.net(VB6)String类型、中文、日文与Unicode互相转换 ***需要引用正则表达式 Imports System.Text.RegularExpressions ①将unicode转成中文,如:ABC \u8033\u9EA6 12345,转后为:ABC 耳麦 12345 '将unicode转...
  • import java.text.NumberFormat;//Java 给数字左边补0public class NumberFormatTest { public static void main(String[] args) { // 待测试数据 int i = 1; // 得到一个NumberFormat的实例 NumberFormat nf...
  • 不要求调用vb中的indexof功能,而是自己写。应该是类似于把string变成chars()然后自己查找位置之类的,但是不会写,求大神
  • 1.ASC()是将全角转换为半角的函数,当字符为全角时,占用两个字节,例如...例如string(5,b)则输出bbbbb,string后取的是字符,而不是字符串,例如string(5,bcd)输出也会是bbbbb,取第一个字符组成字符串 ...
  • 我在VB中调用一个dll,dll中函数为long msg(LPSTR str),我如何将在VB中定义的string类型的参数转换为LPSTR传递到DLL函数中?
  • VB.Net反编译时StringType.StrCmp用C#的函数string.Compare替换 转载于:https://www.cnblogs.com/GDLMO/archive/2007/12/19/1006294.html
  • C++ fstream文件流读 字符串string与b VB ListView控件各种
  • VB 6.0Byte数组和String转换

    千次阅读 2012-04-07 16:09:09
    VB里,Byte数组和String可以互相赋值,利用这个特性处理字符串非常方便。 如果是处理大量文本,以下用法应该熟悉。 字符串与Byte数组互相赋值: tBytes()=tString tString=tBytes() 需要注意的是...
  • VB中如何取出来函数结果,执行存储过程的结果呢?存储过程结果为一个Number, 没怎么写过VB麻烦大神帮忙看看 KS = ClsOnlineServiceCall.SPDB.Instance.B10MatchedApplications(m_connectionString, items(0) + ...
  • '作为测试,添加1个按钮,两个listboxPrivate Declare Sub CopyMemory Lib "kernel32" Alias _ "RtlMoveMemory" (dest As Any, source As Any, _ ByVal numBytes As...Sub InsertStringItem(strArr() As String, ByV...
  • 看了网上各种方法但是都不好用,用了tostring,...""和DirectCast(deliveryMst(i).CaseCode6, String) = "" 2,deliveryMst(i).CaseCode5 IsNot Nothing AndAlso deliveryMst(i).CaseCode5 IsNot DBNull.Value,都不好用
  • vb.net的-String

    2008-06-26 14:35:00
    转载于:https://www.cnblogs.com/lizunicon/archive/2008/06/26/1230409.html
  • 来自公众号:新世界杂货铺前言继Go的HTTP请求之——HTTP1.1请求流程分析之后,中间断断续续,历时近一月,终于才敢开始码字写下本文。阅读建议HTTP2.0在建立TCP连接和安全的TLS传输通道与HTTP1.1的流程基本一致。...
  • vb.net的String数据类型

    2011-05-27 16:30:00
    vb.net,一个字符串可包含大约2亿(2的31次方)个Unicode字符,字符的机内码从0到65535,前128个字符代表英文字母及标准键盘上的字符, 128到255个字符代表特殊的字符,如拉丁字母、货币符号、分数等。...
  • '从excel拿到有时间的字符串并截取, Dim reportDateFromExcel = xlSheet.Cells(2, 2).Value().ToString ' 'Report Date 31/12/2018' Dim reprotDateStr = Strings.Right(reportDateFromExcel, 10) Dim ...
  • vb string类型变量在内存的表示? 1 一般来说,vb字符串都使用UNICODE表示,不管汉字还是英文字符都应该是两个字节。 eg.一个字符串在内存,占的字节数应该是 总内存=字符个数*2字节 2 内存分布应该是汉字两个字节...
  • vb中val是什么意思?随着时代的发展,越来越多的的新词汇出现在我们的生活中,下面就和美文阅读网小编一起来了解一下vb中val是什么意思吧。vb中val是什么意思这是一个把字符串转为数值的函数,将S转为它的数值形式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,745
精华内容 698
关键字:

vb中string