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. 微软的帮助文档自身说明不完全;
其中说到:
"许多 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类型.