Hi,
I want to write and read some information and configuration in a ini file. I now found a code-snippet for reading and writing from/into ini files:
Private
Declare Function GetPrivateProfileStringA Lib "kernel32" _Alias "GetPrivateProfileStringA" (ByVal sSectionName As _
String, ByVal sKeyName As String, ByVal sDefault As String, _
ByVal sReturnedString As String, ByVal lSize As Long, _
ByVal sFileName As String) As Long
Private Declare Function WritePrivateProfileStringA Lib "kernel32.dll" ( _
ByVal lpSection As String, _
ByVal lpSetting As String, _
ByVal lpValue As String, _
ByVal lpFileName As String _
) As Long
Writing works very well. But if I try to read values, I get an exception called 'PInvokeStackImbalance'. Unfortunatelly I can't find the mistake and the reason for this behaviour. The function ist called like:
Dim s As String = ""
Dim n As Long
n = GetPrivateProfileStringA(txtReadSection.Name, txtReadKey.Name, "default", s, 10, IniPath())
Return Microsoft.VisualBasic.Right(s, n)
The function IniPath() returns the name and path of the file properly. Even if I use strings instead of the textfields 'txtReadSection.Text' and 'txtReadKey.Text', the exception occurs.
The exact message by VB 2005 is:
PInvokeStackImbalance wurde erkannt.
Message: Ein Aufruf an die PInvoke-Funktion "Appname.Form2::GetPrivateProfileStringA" hat das Gleichgewicht des Stapels gestort. Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur uberein. Uberprufen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht verwalteten Zielsignatur ubereinstimmen.
Can you help me

Read from ini-File: PInvokeStackImbalance
Destroy89
IIt used to be that a long was the 32 bit entity. Now it's an integer that is 32 bits.
Change all longs to integers and enjoy.
kunalmukherjii
I don't know what the hell is going on with vb but I found the solution: I declared the variable 's' like this:
Dim s As String = ""
The result s has no content, no chars. But if I declare s like this:
Dim s As String = " "
everything is going the right way. If I assign two spaces to s before assigning the result, the result will ever be 2 chars long. It doens't matter, how many chars the result has.
MKB
But there's a next problem: After a response, 'n' is filled, but 's' doesn't contain any information. Did I forget something
Thank you in advance.
Reed Robison
API Calls have the potential for instability - not because they don't work, but because they are used incorrectly. If you use a lot of WinAPI calls I'd recommend getting a book - the best book ever is by Dan Appleman, "The Visual Basic Programmers Guide to the API" (It's for VB6, but if you wish to use APIs you need a thorough understanding of how they work). Luckily, we don't need the majority of them, now.
The INI API Calls require the string that you pass to be 'pre-padded': the string is actually a return from the API: off the top of my head, it needs to be a specific length, one of the parameters is the length that you are passing. lsize in the above example.
The returned string will be null terminated (something that VB programmers never usually have to worry about such things). You can play around with some ideas for stripping any unwanted characters from the string.
The idea behind this API is that you are assigning some memory for the API call to use, and return the value by putting data into that memory region. By passing a zero length string, you are actually corrupting memory - it may appear to work this week, but next week could be disaster. This is one reason that API calls are fast: they generally populate a region of memory with no regard as to what's there, or who owns it.
As a side note, I think you can actually pass a stringbuilder object as a parameter, instead of a string, but I haven't tried that.
Jean-Marc Flamand dit le_beluet
I'm not sure what your doing there but the following. will output
90
4
0
which is just what I'd expected
Module Module1
Sub Main()
Dim s As String = " "
Console.WriteLine(s.Length.ToString)
s = "test"
Console.WriteLine(s.Length.ToString)
s = ""
Console.WriteLine(s.Length.ToString)
End Sub
End Module
Can you better describe you scenario so I can try and repro it.
John_C
bener
You are welcome.