From: Marc Hillman on 2 Mar 2010 16:23 Thanks Jason - I have read the documentation - several times. Many sites recommend to use of StringBuilder over String because String is not immutable (whatever that means). As mention by Armin - pansichar is a pointer to an ANSI char string, and it's passed by reference. The important symptom here is that it all works fine on very small programs, but not on larger ones. Somehow the return variables location in memory is coming into play. "Jason Keats" <jkeats(a)melbpcDeleteThis.org.au> wrote in message news:uHZrQJiuKHA.796(a)TK2MSFTNGP05.phx.gbl... > Marc Hillman wrote: >> I've been bashing my head up against a brick wall for 4 days, and I've >> reached the limit of my frustration and knowledge. I'd appreciate some >> ideas on what I'm doing wrong. >> >> I have a simple Visual Basic Express 2008 program. It calls a DLL >> (supplied by others). Calls to the DLL in small (trivial) programs work >> fine. When the program grows in size I get a "vshost.exe has stopped >> working" message. It happens when I call any dll function that tries to >> return a string. I have googled and tried everything. >> >> The full program is a few thousand lines, much of it auto coded because >> of database access, but the critical bits are below. >> >> In fileOziExplorer.vb >> Imports System.Text >> Module OziExplorer >> Declare Ansi Function oziGetOziVersion Lib "oziapi" (ByRef Version As >> StringBuilder, ByRef DataLength As Integer) As Integer >> End Mdule >> >> In file Form1.vb >> Dim oziVersion As New StringBuilder(250), vDatalength As Integer >> i = oziGetOziVersion(oziVersion, vDatalength) >> >> When the i=oziGetOziVersion is called I get the vshost error message. >> >> I have hacked vshost.exe to disable DEP. >> >> I'm totally out of ideas. All the obvious fixes have been tried. >> >> >> > > Have you read the documentation? > > http://www.oziexplorer3.com/oziapi/oziapi_docs.html#oziGetOziVersion > > For starters, I would change "As StringBuilder" to "As String". >
From: Tom Shelton on 2 Mar 2010 17:29 On Mar 2, 9:01 am, Armin Zingler <az.nos...(a)freenet.de> wrote: > Am 02.03.2010 14:01, schrieb Marc Hillman: > > > Good news and bad news. > > > The app no longer crashes, but the return results are curious. For the line > > i = oziGetOziVersion(oziVersion, vDatalength) > > > 1. vDatalength is 0 > > 2. when I assign st (a string)=oziVersion.tostring the result is gibberish > > 3. oziVersion.Length is correct (6) > > > I think I'm close. How do I get the string out of the StringBuilder? > > I had searched for the function declaration and found > > function oziGetOziVersion(var Version:pansichar;var DataLength:integer):integer;stdcall; > > I'm not sure how to translate "var Version:pansichar". I guess that "p"ansichar is a > pointer to an ANSI char/string. In addition, var means it's passed by reference. > So a pointer to a pointer is passed, right? By heart, I don't know how to declare it > with the type String(builder). Anyone? > > -- > Armin Looking at the documentation, I don't think you can use StringBuilder here. It sounds like the API returns a pointer to an internal buffer. Which you then need to copy to your own string. The buffers may be reused. So, my guess is that this function has to be declared like: Declare Function oziGetOziVersion Lib "oziapi" (ByRef vVersion As IntPtr, ByRef DataLength As Integer) As Integer Then used something like: Dim strPtr As IntPtr Dim vLength As Integer oziGetOziVersion (strPtr, vLength) dim bufferptr as intptr = marshal.ReadIntPtr(strPtr) string version = marshal.ptrtostringansi(bufferprt, vlength) something like that anway... if i read the documentation right :)
From: Armin Zingler on 2 Mar 2010 18:53 Am 02.03.2010 23:29, schrieb Tom Shelton: > > something like that anway... if i read the documentation right :) Yes, thanks. That what I wasn't sure about. -- Armin
From: Tom Shelton on 2 Mar 2010 20:01 On 2010-03-02, Armin Zingler <az.nospam(a)freenet.de> wrote: > Am 02.03.2010 23:29, schrieb Tom Shelton: >> >> something like that anway... if i read the documentation right :) > > Yes, thanks. That what I wasn't sure about. > What I'm not sure is if it's returning a ptr to a ptr to the buffer or a ptr to the buffer, so some adjustment maybe needed to avoid a nasty crash :) -- Tom Shelton
From: Marc Hillman on 3 Mar 2010 03:08 Success Tom - thanks a million. Did not need the "dim bufferptr as intptr = marshal.ReadIntPtr(strPtr)" statement." IntPtr is new to me, as is Marshal, but I think I understand enough to fix all the other similar issues. I still don't understand why 'simple' version of the code work with String types, but it's great to finally have a solution. Thanks again. It never ceases to amaze me the number of people who willingly help others for no obvious reward. "Tom Shelton" <tom_shelton(a)comcast.net> wrote in message news:3472b5dd-6b44-4cd1-b2a7-686db2ac0da9(a)m27g2000prl.googlegroups.com... > On Mar 2, 9:01 am, Armin Zingler <az.nos...(a)freenet.de> wrote: >> Am 02.03.2010 14:01, schrieb Marc Hillman: >> >> > Good news and bad news. >> >> > The app no longer crashes, but the return results are curious. For the >> > line >> > i = oziGetOziVersion(oziVersion, vDatalength) >> >> > 1. vDatalength is 0 >> > 2. when I assign st (a string)=oziVersion.tostring the result is >> > gibberish >> > 3. oziVersion.Length is correct (6) >> >> > I think I'm close. How do I get the string out of the StringBuilder? >> >> I had searched for the function declaration and found >> >> function oziGetOziVersion(var Version:pansichar;var >> DataLength:integer):integer;stdcall; >> >> I'm not sure how to translate "var Version:pansichar". I guess that >> "p"ansichar is a >> pointer to an ANSI char/string. In addition, var means it's passed by >> reference. >> So a pointer to a pointer is passed, right? By heart, I don't know how to >> declare it >> with the type String(builder). Anyone? >> >> -- >> Armin > > Looking at the documentation, I don't think you can use StringBuilder > here. It sounds like the API returns a pointer to an internal > buffer. Which you then need to copy to your own string. The buffers > may be reused. So, my guess is that this function has to be declared > like: > > Declare Function oziGetOziVersion Lib "oziapi" (ByRef vVersion As > IntPtr, ByRef DataLength As Integer) As Integer > > Then used something like: > > Dim strPtr As IntPtr > Dim vLength As Integer > > oziGetOziVersion (strPtr, vLength) > dim bufferptr as intptr = marshal.ReadIntPtr(strPtr) > string version = marshal.ptrtostringansi(bufferprt, vlength) > > something like that anway... if i read the documentation right :)
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Windows Service Next: Dynamically adding menu items and their OnClick events |