473,811 Members | 3,057 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

StrPtr Question

dev
Hello,
How can the following code be converted to VB.Net? I am mostly interested
in how to handle the StrPtr calls in the function.

Private Declare Function PathRelativePat hToW Lib "shlwapi.dl l" _
(ByVal pszPath As Long, _
ByVal pszFrom As Long, _
ByVal dwAttrFrom As Long, _
ByVal pszTo As Long, _
ByVal dwAttrTo As Long) As Boolean

Public Function GetRelativePath (ByVal sFromDirectory As String, _
ByVal sToFile As String) As String

Dim sRelativePath As String
Dim bResult As Boolean

Const MAX_PATH As Long = 260

sRelativePath = Space(MAX_PATH)

' Set "Attr" to vbDirectory for directories and 0 for files
bResult = PathRelativePat hToW(StrPtr(sRe lativePath),
StrPtr(sFromDir ectory), _
vbDirectory, StrPtr(sToFile) , 0)

If bResult Then
GetRelativePath = Left(sRelativeP ath, InStr(sRelative Path,
Chr(0)) -1)
End If
End Function

TIA,
Steve
Nov 20 '05 #1
16 5438
Steve,
How can the following code be converted to VB.Net? I am mostly interested in how to handle the StrPtr calls in the function. StrPtr is no more! As it is no longer needed!

I would recommend something like:

Declare Auto Function PathRelativePat hTo Lib "shlwapi.dl l" (ByVal
pszPath As System.Text.Str ingBuilder, ByVal pszFrom As String, ByVal
dwAttrFrom As FileAttributes, ByVal pszTo As String, ByVal dwAttrTo As
FileAttributes) As Boolean

Public Function GetRelativePath (ByVal sFromDirectory As String,
ByVal sToFile As String) As String
Const MAX_PATH As Integer = 260

Dim sRelativePath As New System.Text.Str ingBuilder(MAX_ PATH)

Dim bResult As Boolean

' Set "Attr" to vbDirectory for directories and 0 for files
bResult = PathRelativePat hTo(sRelativePa th, sFromDirectory,
FileAttributes. Directory, sToFile, 0)

If bResult Then
Return sRelativePath.T oString()
Else
Return Nothing
End If
End Function

Passing the output string as a StringBuilder is safest as Strings themselves
are immutable. Just remember to initialize the capacity of the StringBuilder
to the maximum size of characters that may be returned.

Both String & Stringbuilder are correctly converted when defined in
parameters. String is good for input parameters, StringBuilder are good for
Output & Input/Output parameters.

Declaring dwAttrFrom & dwAttrTo as System.IO.FileA ttributes simplifies the
usage of the parameters.

Declaring the function as Auto, ensures that the Unicode strings are
converted properly respective to the OS being run on. On NT based OS the
strings will stay Unicode & the W version of the function is called, on 95
based OS the strings will be converted to Ansi and the A version of the
function will be called!

BTW: Interesting function I needed it a few weeks ago! I'll have to file it
away in my grab bag of functions.

Hope this helps
Jay

"dev" <de****@nospam. com> wrote in message
news:ed******** ******@TK2MSFTN GP10.phx.gbl... Hello,
How can the following code be converted to VB.Net? I am mostly interested in how to handle the StrPtr calls in the function.

Private Declare Function PathRelativePat hToW Lib "shlwapi.dl l" _
(ByVal pszPath As Long, _
ByVal pszFrom As Long, _
ByVal dwAttrFrom As Long, _
ByVal pszTo As Long, _
ByVal dwAttrTo As Long) As Boolean

Public Function GetRelativePath (ByVal sFromDirectory As String, _
ByVal sToFile As String) As String

Dim sRelativePath As String
Dim bResult As Boolean

Const MAX_PATH As Long = 260

sRelativePath = Space(MAX_PATH)

' Set "Attr" to vbDirectory for directories and 0 for files
bResult = PathRelativePat hToW(StrPtr(sRe lativePath),
StrPtr(sFromDir ectory), _
vbDirectory, StrPtr(sToFile) , 0)

If bResult Then
GetRelativePath = Left(sRelativeP ath, InStr(sRelative Path,
Chr(0)) -1)
End If
End Function

TIA,
Steve

Nov 20 '05 #2
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
Passing the output string as a StringBuilder is safest as Strings themselves
are immutable. Just remember to initialize the capacity of the StringBuilder
to the maximum size of characters that may be returned.


When using VB.NET's 'Declare', it's not necessary to declare the
parameter as 'StringBuilder' . VB.NET will do the marshalling
automatically.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #3
Herfried,
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete
Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.

Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP
gave requires a buffer passed in, to put the output string in. Passing a
System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified an
immutable object, which may lead to subtle runtime bugs elsewhere.

Based on the above book and other articles in MSDN Magazine on P/Invoke
using StringBuilder for output strings is the safest & easiest method to
use.

So although you can send in a System.String to an output parameter of an API
call, I would seriously not recommend it as you are running a high risk of
corrupting the runtime. Of course using any API call you are running a risk
of corrupting the runtime time, why elevate that risk?

Hope this helps
Jay

"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:uw******** ********@TK2MSF TNGP11.phx.gbl. ..
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
Passing the output string as a StringBuilder is safest as Strings themselves are immutable. Just remember to initialize the capacity of the StringBuilder to the maximum size of characters that may be returned.


When using VB.NET's 'Declare', it's not necessary to declare the
parameter as 'StringBuilder' . VB.NET will do the marshalling
automatically.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #4
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete
Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.

Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP
gave requires a buffer passed in, to put the output string in. Passing a
System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified an
immutable object, which may lead to subtle runtime bugs elsewhere.
ACK. But AFAIR it won't cause problems (except maybe performance
problems) when passing the string.
Based on the above book and other articles in MSDN Magazine on P/Invoke
using StringBuilder for output strings is the safest & easiest method to
use.
When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. When using VB.NET's 'Declare', VB.NET
will automatically create the '<MarshalAs(Unm anagedType.VBBy RefStr)>':

<http://msdn.microsoft. com/library/en-us/cpref/html/frlrfSystemRunt imeInteropServi cesUnmanagedTyp eClassTopic.asp >
So although you can send in a System.String to an output parameter of an API
call, I would seriously not recommend it as you are running a high risk of
corrupting the runtime. Of course using any API call you are running a risk
of corrupting the runtime time, why elevate that risk?


As mentioned above, I don't think that there is a risk in this case when
passing the string directly.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #5
Herfried,
Interesting!

I missed the section in the book on the VBByRefStr, thanks for pointing
VBByRefStr out as it is a handy MarshalAs parameter to know!

Note: Adam's book states the following about
MarshalAs(Unman agedType.VBByRe fStr), after explaining how it works in VB.NET
& how to use it in C#:

"This is not recommended, however. Even in Visual Basic .NET,
you should use StringBuilder rather then String if backwards
compatibility with existing source code isn't important"

Then he follows that with:

"TIP: You should use StringBuider to represent a buffer in
Visual Basic .NET, just like you would in C#.
Using String types for this case is simply a second
option for backward compatibility."

I'm sure when I read the above section 6 months ago the above info is what
stuck with me, and VBByRefStr slipped away. ;-)

I'm not certain what "backward compatibility" he is referring to, I would
think VB6. I wish he would dig deeper into why it is not recommended! Maybe
I just have not got to that section of the book yet ;-)

Looking closer at Adam's book, he indicates that you should use the
InAttribute & OutAttribute (from System.Runtime. InteropServices ) to help
minimize the amount of copying going on, as StringBuilder & String will
actually copy the buffer for the call, then copy the buffer back. I suspect
VBByRefStr is doing its own amount of copying...

I normally try to include InAttribute & OutAttribute in my Declares &
DllImports.
When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. I'll let you, now that I know its safe!

However! I will continue to recommend StringBuilder even with Declare. As to
me it is more obvious what is happening (strings are immutable) and it
allows converting back & forth from DllImport easier.
As mentioned above, I don't think that there is a risk in this case when
passing the string directly. In light of "MarshalAs(Unma nagedType.VBByR efStr)" I agree, there is no
greater risk then normal API calls.

Thanks for the info
Jay
"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:ut******** *******@TK2MSFT NGP09.phx.gbl.. . * "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.
Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP
gave requires a buffer passed in, to put the output string in. Passing a
System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified an immutable object, which may lead to subtle runtime bugs elsewhere.
ACK. But AFAIR it won't cause problems (except maybe performance
problems) when passing the string.
Based on the above book and other articles in MSDN Magazine on P/Invoke
using StringBuilder for output strings is the safest & easiest method to
use.


When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. When using VB.NET's 'Declare', VB.NET
will automatically create the '<MarshalAs(Unm anagedType.VBBy RefStr)>':

<http://msdn.microsoft.com/library/en...mRuntimeIntero
pServicesUnmana gedTypeClassTop ic.asp>
So although you can send in a System.String to an output parameter of an API call, I would seriously not recommend it as you are running a high risk of corrupting the runtime. Of course using any API call you are running a risk of corrupting the runtime time, why elevate that risk?


As mentioned above, I don't think that there is a risk in this case when
passing the string directly.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #6
dev
Thanks, I had Googled StrPtr and most of the answers stated the the way to
handle StrPtr in VB.Net was specific to how StrPtr was being used in the
original function., VB6 in this case.

"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:ut******** *******@TK2MSFT NGP09.phx.gbl.. .
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.
Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP
gave requires a buffer passed in, to put the output string in. Passing a
System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified an immutable object, which may lead to subtle runtime bugs elsewhere.
ACK. But AFAIR it won't cause problems (except maybe performance
problems) when passing the string.
Based on the above book and other articles in MSDN Magazine on P/Invoke
using StringBuilder for output strings is the safest & easiest method to
use.


When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. When using VB.NET's 'Declare', VB.NET
will automatically create the '<MarshalAs(Unm anagedType.VBBy RefStr)>':

<http://msdn.microsoft.com/library/en...mRuntimeIntero
pServicesUnmana gedTypeClassTop ic.asp>
So although you can send in a System.String to an output parameter of an API call, I would seriously not recommend it as you are running a high risk of corrupting the runtime. Of course using any API call you are running a risk of corrupting the runtime time, why elevate that risk?


As mentioned above, I don't think that there is a risk in this case when
passing the string directly.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #7
Dev,
Did you see my earlier post? I gave you a complete working example on how to
call the API. As StrPtr does not exist in VB.NET!

You need to use one of the following Declare statements:

Declare Auto Function PathRelativePat hTo Lib "shlwapi.dl l" (ByVal
pszPath As System.Text.Str ingBuilder, ByVal pszFrom As String, ByVal
dwAttrFrom As FileAttributes, ByVal pszTo As String, ByVal dwAttrTo As
FileAttributes) As Boolean

Declare Auto Function PathRelativePat hTo Lib "shlwapi.dl l" (ByVal
pszPath As String, ByVal pszFrom As String, ByVal
dwAttrFrom As FileAttributes, ByVal pszTo As String, ByVal dwAttrTo As
FileAttributes) As Boolean

The second one maybe easier for VB6 developers to follow, however I prefer
the first one. Both should do the job equally well for you!

Hope this helps
Jay
"dev" <de****@nospam. com> wrote in message
news:uZ******** **********@TK2M SFTNGP11.phx.gb l...
Thanks, I had Googled StrPtr and most of the answers stated the the way to
handle StrPtr in VB.Net was specific to how StrPtr was being used in the
original function., VB6 in this case.

"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:ut******** *******@TK2MSFT NGP09.phx.gbl.. .
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.
Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP gave requires a buffer passed in, to put the output string in. Passing a System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified
an
immutable object, which may lead to subtle runtime bugs elsewhere.
ACK. But AFAIR it won't cause problems (except maybe performance
problems) when passing the string.
Based on the above book and other articles in MSDN Magazine on
P/Invoke using StringBuilder for output strings is the safest & easiest method to use.


When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. When using VB.NET's 'Declare', VB.NET
will automatically create the '<MarshalAs(Unm anagedType.VBBy RefStr)>':

<http://msdn.microsoft.com/library/en...mRuntimeIntero pServicesUnmana gedTypeClassTop ic.asp>
So although you can send in a System.String to an output parameter of
an API call, I would seriously not recommend it as you are running a high
risk
of corrupting the runtime. Of course using any API call you are running a risk of corrupting the runtime time, why elevate that risk?


As mentioned above, I don't think that there is a risk in this case when
passing the string directly.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>


Nov 20 '05 #8
Cor
Hi Jay B.
That is the Jay B we know.
:-)
Cor

Nov 20 '05 #9
Herfried,
I believe I figured out why StringBuilder is recommended! ;-)

<MarshalAs(Unma nagedType.VBByR efStr)> can only be used with "InOut"
parameters, if you start adding InAttribute or OutAttribute to the declare
statement you need to give a MarshalAs with the 'regular' string types
<MarshalAs(Unma nagedType.LPTSt r)> for example, other wise you get an
exception from the Marshaller

If you are not concerned with the InAttribute or OutAttribute then the
"default" behavior of VBByRefStr is reasonable for the Declare statement. As
it mimics what VB6 would do.

As I stated in my other post I normally include InAttribute & OutAttribute
on my Declare statements...

Hope this helps
Jay

"Herfried K. Wagner [MVP]" <hi************ ***@gmx.at> wrote in message
news:ut******** *******@TK2MSFT NGP09.phx.gbl.. .
* "Jay B. Harlow [MVP - Outlook]" <Ja************ @msn.com> scripsit:
My answer is based on what Adam Nathan wrote in ".NET and COM - The Complete Interoperabilit y Guide" from SAMS press. Plus other MSDN Magazine articles.
Yes VB.NET will marshal the string correctly for you.

However! Remember that a System.String is immutable, the API that the OP
gave requires a buffer passed in, to put the output string in. Passing a
System.String for this buffer breaks the "immutable" intent of the
System.String class. So although it may appear to work you just modified an immutable object, which may lead to subtle runtime bugs elsewhere.
ACK. But AFAIR it won't cause problems (except maybe performance
problems) when passing the string.
Based on the above book and other articles in MSDN Magazine on P/Invoke
using StringBuilder for output strings is the safest & easiest method to
use.


When using 'DllImport': Yes. When using 'Declare' it's not necessary
and IMHO not the "preferred" way. When using VB.NET's 'Declare', VB.NET
will automatically create the '<MarshalAs(Unm anagedType.VBBy RefStr)>':

<http://msdn.microsoft.com/library/en...mRuntimeIntero
pServicesUnmana gedTypeClassTop ic.asp>
So although you can send in a System.String to an output parameter of an API call, I would seriously not recommend it as you are running a high risk of corrupting the runtime. Of course using any API call you are running a risk of corrupting the runtime time, why elevate that risk?


As mentioned above, I don't think that there is a risk in this case when
passing the string directly.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
5045
by: Stevey | last post by:
I have the following XML file... <?xml version="1.0"?> <animals> <animal> <name>Tiger</name> <questions> <question index="0">true</question> <question index="1">true</question> </questions>
7
2668
by: nospam | last post by:
Ok, 3rd or is it the 4th time I have asked this question on Partial Types, so, since it seems to me that Partial Types is still in the design or development stages at Microsoft, I am going to ask it differently. FOUR QUESTIONS: The background: I got three (3) files
3
3096
by: Ekqvist Marko | last post by:
Hi, I have one Access database table including questions and answers. Now I need to give answer id automatically to questionID column. But I don't know how it is best (fastest) to do? table before rowID answID qryrow questionID datafield 1591 12 06e 06e 06e question 1593 12 06f 06f 06f question 1594 12 answer to the question 06f
10
3444
by: glenn | last post by:
I am use to programming in php and the way session and post vars are past from fields on one page through to the post page automatically where I can get to their values easily to write to a database or continue to process on to the next page. I am now trying to learn ASP to see if we can replace some of our applications that were written in php with an ASP alternative. However, after doing many searches on google and reading a couple...
11
16822
by: Tim | last post by:
I've searched my help files, and all I can find is that the StrPtr() function is not supported. Is there a suitable replacement in VB.Net?
10
3745
by: Rider | last post by:
Hi, simple(?) question about asp.net configuration.. I've installed ASP.NET 2.0 QuickStart Sample successfully. But, When I'm first start application the follow message shown. ========= Server Error in '/QuickStartv20' Application. -------------------------------------------------------------------------------- Configuration Error Description: An error occurred during the processing of a configuration file
53
4100
by: Jeff | last post by:
In the function below, can size ever be 0 (zero)? char *clc_strdup(const char * CLC_RESTRICT s) { size_t size; char *p; clc_assert_not_null(clc_strdup, s); size = strlen(s) + 1;
56
4812
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
2
4288
by: Allan Ebdrup | last post by:
Hi, I'm trying to render a Matrix question in my ASP.Net 2.0 page, A matrix question is a question where you have several options that can all be rated according to several possible ratings (from less to more for example). I have a question object that has two properties that contain the collections Options and Ratings. now I want this kind of layout: --- Rating1 Rating2 Rating3 Option 1 () () ...
0
9605
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10647
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10384
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10130
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9204
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6887
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5553
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5692
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3017
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.