您的位置:首页 > 编程语言 > VB

API 在vb.net中應用注意事項

2004-12-22 09:58 477 查看
API声明如下:(照MSDN上声明的)
    Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias _
    "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
    lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString _
    As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

调用如下:
                      ......
        Dim strBuffer As New String(CChar(" "), 50)
        Dim ret As Long
        ret = GetPrivateProfileStringKey(CFG_GROUP_NET, CFG_KEY_SERVER_IP, _
            DEFAULT_SERVER_IP, strBuffer, 50, m_FilePath)

        GetServerIP = Left(strBuffer, InStr(strBuffer, Chr(0)) - 1)
                      ......

其中, 全大写的为自己定义的全局字符串常量;

结果, 调用失败, 无法取得配置文件中的键值. WritePrivateProfileString执行成功.问题
真的很奇怪! 我看了一些帖子, 自己认为可能的疑点有两处:
1. 有些帖子指出API的声明中返回值应该是Int32? 马上去试验一下;

2. INI文件的路径我用的是如下方式:
    m_FilePath = Application.StartupPath + "/" + CFG_FILE_NAME
是不是因为要用"//"来分隔路径引起的问题?但估计问题不在这里,因为在WritePrivateProfileString调用的时候也用的这个路径, 是成功的.

    希望知道的朋友可以帮助一把, 谢谢大家!

哈哈, 各位, 问题终于解决了, 应该说发生这个错误的原因有两个:
1. 微软的帮助文档自身说明不完全;

先请参看微软的帮助文档:
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/vbcon/html/vbconupgraderecommendationadjustdatatypesforwin32apis.asp

其中说到:

"许多 API 可以象在 Visual Basic 6.0 中那样被正确地使用,但是需要说明的是必须相应地调整数据类型。目前,Visual Basic 6.0 的 Long 数据类型为 Visual Basic .NET 的 Integer 数据类型,而 Visual Basic 6.0 的 Integer 数据类型为 Visual Basic .NET 的 Short 数据类型。升级期间,这些更改将自动完成,简单的 API 与在 Visual Basic 6.0 中的工作方式完全相同。"

好, 这段没有问题, 说的很好, 也解释的很清楚, 但问题出在它后面的一段:

"有三种可能需要进行一些更改的情况。第一种情况是向 API 传递包含定长串或字节数组的用户定义类型时。在 Visual Basic .NET 中可能需要更改代码,向用户定义的类型中的每个定长串或字节数组中添加 MarshallAs 属性(来自 System.Runtime.InteropServices)。第二种情况是在 Declare 语句中使用 As Any 变量类型时。Visual Basic .NET 中不支持这种情况。As Any 类型的变量通常用于传递为字符串或 Null 的变量;您可以通过声明两种格式的 API(一种为 long,一种为 string)替换此 Visual Basic 6.0 的用法。例如,GetPrivateProfileString API 有一个 As Any 类型的参数 lpKeyName:

Private Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString _
As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
可通过用两种版本替换 Declare 来去除“As Any”,其中一种版本接受长型,一种版本接受字符串:

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString _
As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32" _
Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Long, ByVal lpDefault As String, ByVal _
lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName _
As String) As Long"

不知道大家发现没有, 最开始已经提到了Visual Basic 6.0 的 Long 数据类型为 Visual Basic .NET 的 Integer 数据类型, 但是在接下来的GetPrivateProfileString例子中却就犯了
这样一个毛病, vb6的GetPrivateProfileString参数声明中的ByVal nSzie As Long以及函数的返回在VB.net的改正示例中却还是Long类型, 没有修正为Integer!!!!也就是说微软犯了一个很弱智的错误,应该说误导了不少的开发者;

2. 我的VB功力还是欠缺; 所以以致无法及时发现其中的端倪, 对于VB6向VB.net迁移的细节了解的不够;

最后, 给出GetPrivateProfileString的正确VB.net 声明

    Declare Function WritePrivateProfileString Lib "kernel32" Alias _
        "WritePrivateProfileStringA" (ByVal lpApplicationName As String, _
        ByVal lpKeyName As String, ByVal lpString As String, ByVal lpFileName As String) As Integer

    Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias _
    "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
    lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString _
    As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer

    Declare Function GetPrivateProfileStringNullKey Lib "kernel32" _
    Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, _
    ByVal lpKeyName As Long, ByVal lpDefault As String, ByVal _
    lpReturnedString As String, ByVal nSize As Integer, ByVal _
    lpFileName As String) As Integer

注意, 其中原来VB6Long参数类型都要改正为Integer类型.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息