473,388 Members | 1,298 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

Does String mashal default to UnmanagedType.LPTStr

Been reading some of the Marshal doc and am a little confused.

Anyway, I've been using the following and it works OK.

Public Declare Auto Function SHGetFolderPath Lib "shell32.dll" (ByVal hWnd
As Integer, _

ByVal nFolder As Integer, ByVal nToken As Integer, _

ByVal dwFlags As Integer, _

<MarshalAs(UnmanagedType.LPTStr)> ByVal lpszPath As String) As Boolean

Tried this because I saw some place (not in the doc) that
UnmanagedType.LPTStr was the default for String. This works too.

Public Declare Auto Function SHGetFolderPath Lib "shell32.dll" (ByVal hWnd
As Integer, _

ByVal nFolder As Integer, ByVal nToken As Integer, _

ByVal dwFlags As Integer, _

ByVal lpszPath As String) As Boolean

Is that correct. I.e., in VB, String mashal defaults to
UnmanagedType.LPTStr so UnmanagedType.LPTStr need not be included??

This is how it's used:

Dim lPath As String = Space(260)

If Library.Shell.SHGetFolderPath(0, k, 0, 0, lPath) = 0 Then

lPath = lPath.Trim

lPath = lPath.Substring(0, lPath.Length - 1)

GetSpecialPath = lPath

End If

Finally, is that the correct way to do it or should I use StringBuilder.

If it's not the correct way, why not? It appears to work OK.

Thanks in advance


Nov 21 '05 #1
8 5732
On 2005-07-02, **Developer** <RE*************@a-znet.com> wrote:
Been reading some of the Marshal doc and am a little confused.

Anyway, I've been using the following and it works OK.

<snip>

Finally, is that the correct way to do it or should I use StringBuilder.

For buffers populated by the called function, you really should use
StringBuilder.
If it's not the correct way, why not? It appears to work OK.


Here are a couple of reasons:

1) Strings in .NET are immutable. By passing a type of string to the
marshaller, you are causing it to do extra work. Basically, the
marshaller, must copy data to a buffer, call the function, and then copy
the buffer back to your string. When you use a StringBuilder, it just
passes the buffer. You probably won't notice the performance hit unless
your in a long loop or something... But, still why cause the marshaller
to work harder then it needs to :)

2) This technique of using a string as a modifiable buffer will not work
in other languages - for example C#. Not that you probably care, but if
you have to do work in that language suddenly and try to declare the
function the way you did, you might spend needless time debuggin why it
didn't work.

Of course, I have to ask... Do you really need this function? Have
yous seen System.Environment.GetFolderPath?

--
Tom Shelton [MVP]
Nov 21 '05 #2
>
Of course, I have to ask... Do you really need this function? Have
yous seen System.Environment.GetFolderPath?

--
Tom Shelton [MVP]

If I didn't use that function I would not have needed to ask and would not
have the learned what you just told me. I like to try things since that
often bring to the front good things to know.

Thanks a lot
Nov 21 '05 #3


Using StringBuilder do I need to set the Capacity or length or fill it with
anything before the call?
Thanks again

"Tom Shelton" <ts******@YOUKNOWTHEDRILLcomcast.net> wrote in message
news:uF**************@TK2MSFTNGP12.phx.gbl...
On 2005-07-02, **Developer** <RE*************@a-znet.com> wrote:
Been reading some of the Marshal doc and am a little confused.

Anyway, I've been using the following and it works OK.


<snip>

Finally, is that the correct way to do it or should I use StringBuilder.


For buffers populated by the called function, you really should use
StringBuilder.
If it's not the correct way, why not? It appears to work OK.


Here are a couple of reasons:

1) Strings in .NET are immutable. By passing a type of string to the
marshaller, you are causing it to do extra work. Basically, the
marshaller, must copy data to a buffer, call the function, and then copy
the buffer back to your string. When you use a StringBuilder, it just
passes the buffer. You probably won't notice the performance hit unless
your in a long loop or something... But, still why cause the marshaller
to work harder then it needs to :)

2) This technique of using a string as a modifiable buffer will not work
in other languages - for example C#. Not that you probably care, but if
you have to do work in that language suddenly and try to declare the
function the way you did, you might spend needless time debuggin why it
didn't work.

Of course, I have to ask... Do you really need this function? Have
yous seen System.Environment.GetFolderPath?

--
Tom Shelton [MVP]

Nov 21 '05 #4
This is what I've done and it appears to work:

Dim lPath As New System.Text.StringBuilder(Library.Kernel.MAX_PATH)

'Dim lPath As String = Space(260)

If Library.Shell.SHGetFolderPath(0, k, 0, 0, lPath) = 0 Then

" **Developer**" <RE*************@a-znet.com> wrote in message
news:eh**************@tk2msftngp13.phx.gbl...


Using StringBuilder do I need to set the Capacity or length or fill it
with anything before the call?
Thanks again

"Tom Shelton" <ts******@YOUKNOWTHEDRILLcomcast.net> wrote in message
news:uF**************@TK2MSFTNGP12.phx.gbl...
On 2005-07-02, **Developer** <RE*************@a-znet.com> wrote:
Been reading some of the Marshal doc and am a little confused.

Anyway, I've been using the following and it works OK.


<snip>

Finally, is that the correct way to do it or should I use StringBuilder.


For buffers populated by the called function, you really should use
StringBuilder.
If it's not the correct way, why not? It appears to work OK.


Here are a couple of reasons:

1) Strings in .NET are immutable. By passing a type of string to the
marshaller, you are causing it to do extra work. Basically, the
marshaller, must copy data to a buffer, call the function, and then copy
the buffer back to your string. When you use a StringBuilder, it just
passes the buffer. You probably won't notice the performance hit unless
your in a long loop or something... But, still why cause the marshaller
to work harder then it needs to :)

2) This technique of using a string as a modifiable buffer will not work
in other languages - for example C#. Not that you probably care, but if
you have to do work in that language suddenly and try to declare the
function the way you did, you might spend needless time debuggin why it
didn't work.

Of course, I have to ask... Do you really need this function? Have
yous seen System.Environment.GetFolderPath?

--
Tom Shelton [MVP]


Nov 21 '05 #5
**Developer**
In addition to the other comments, the default for VB.NET is
UnmanagedType.VBByRefStr, which allows the string itself (which is
immutable) to be modified by the API call. This allows consistency with VB6
and "simplifies" things.

However as Tom suggests, I normally use StringBuilder, as StringBuilder is
mutable, while String is immutable. Also
<MarshalAs(UnmanagedType.VBByRefStr)> can only be used with "InOut"
parameters, if you start adding InAttribute or OutAttribute to the declare
statement parameters you need to give a MarshalAs with the 'regular' string
types <MarshalAs(UnmanagedType.LPTStr)> 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.

I normally include InAttribute & OutAttribute on my Declare statements...

Hope this helps
Jay
" **Developer**" <RE*************@a-znet.com> wrote in message
news:OY**************@TK2MSFTNGP14.phx.gbl...
| Been reading some of the Marshal doc and am a little confused.
|
| Anyway, I've been using the following and it works OK.
|
| Public Declare Auto Function SHGetFolderPath Lib "shell32.dll" (ByVal hWnd
| As Integer, _
|
| ByVal nFolder As Integer, ByVal nToken As Integer, _
|
| ByVal dwFlags As Integer, _
|
| <MarshalAs(UnmanagedType.LPTStr)> ByVal lpszPath As String) As Boolean
|
|
|
| Tried this because I saw some place (not in the doc) that
| UnmanagedType.LPTStr was the default for String. This works too.
|
| Public Declare Auto Function SHGetFolderPath Lib "shell32.dll" (ByVal hWnd
| As Integer, _
|
| ByVal nFolder As Integer, ByVal nToken As Integer, _
|
| ByVal dwFlags As Integer, _
|
| ByVal lpszPath As String) As Boolean
|
| Is that correct. I.e., in VB, String mashal defaults to
| UnmanagedType.LPTStr so UnmanagedType.LPTStr need not be included??
|
|
|
| This is how it's used:
|
| Dim lPath As String = Space(260)
|
| If Library.Shell.SHGetFolderPath(0, k, 0, 0, lPath) = 0 Then
|
| lPath = lPath.Trim
|
| lPath = lPath.Substring(0, lPath.Length - 1)
|
| GetSpecialPath = lPath
|
| End If
|
|
|
| Finally, is that the correct way to do it or should I use StringBuilder.
|
| If it's not the correct way, why not? It appears to work OK.
|
|
|
| Thanks in advance
|
|
|
|
|
|
Nov 21 '05 #6
<MarshalAs(UnmanagedType.VBByRefStr)> can only be used with "InOut"
parameters, if you start adding InAttribute or OutAttribute to the declare
statement parameters you need to give a MarshalAs with the 'regular'
string
types <MarshalAs(UnmanagedType.LPTStr)> for example, other wise you get an
exception from the Marshaller.

Can't follow this. Seems to say VBByRefStr requires InOut.
Then says In or Out requires LPTStr or something similar.

What am I reading wrong?

Thanks
Nov 21 '05 #7
**Developer**,
| Can't follow this. Seems to say VBByRefStr requires InOut.

That is exactly what I stated: VBByRefStr requires (can only be used for)
InOut parameters. InOut parameters are parameters that do not have an
InAttribute or an OutAttribute attached to them.

InOut parameters are parameters that are marshaled to the unmanaged world &
then marshaled back to the .NET world.

In parameters only need to be marshaled to the unmanaged world (they are
values that go into the API, are not returned.). They have the
System.Runtime.InteropServices.InAttribute attached to them.

http://msdn.microsoft.com/library/de...ClassTopic.asp

Out parameters only need to be marshaled to the .NET world (they are values
that are returned from an API). They have the
System.Runtime.InteropServices.OutAttribute attached to them.

http://msdn.microsoft.com/library/de...ClassTopic.asp

If you read the Win32 API itself, the description of the parameters indicate
if they are In, Out, or InOut.

http://msdn.microsoft.com/library/de...folderpath.asp
| Then says In or Out requires LPTStr or something similar.
Correct, as VB will attempt to put VBByRefStr if you don't include LPTStr.
VBByRefStr with InAttribute or OutAttribute is incompatible.

InAttribute & OutAttribute allow you to "optimize" the API call as they
allow you to indicate that a parameter only needs to be marshaled in a
single direction, allowing the API itself to be quicker.

In the case of SHGetFolderPath , the lpszPath is used to return a String, it
should (*should*) have the OutAttribute on it as it is a return value.
OutAttribute means you need StringBuilder as String with LPTStr is
immutable.

For an example of declaring the API see:

http://www.pinvoke.net/default.aspx/...olderPath.html

Using the Declare syntax:

Private Declare Auto Function SHGetFolderPath Lib "shell32.dll" ( _
ByVal hwndOwner As IntPtr, _
ByVal nFolder As Int32, _
ByVal hToken As IntPtr, _
ByVal dwFlags As Int32, _
<Out()> ByVal pszPath As StringBuilder _
) As Int32

InAttribute is implicit on ByVal value types. String & StringBuiler are
reference types so you need to state if they are In only or Out only,
otherwise InOut is assumed.

I find both the www.pinvoke.net web site & Adam Nathan's book ".NET and
COM - The Complete Interoperability Guide" from SAMS press to be invaluable
when using Declare statements & P/Invoke.

Hope this helps
Jay


Hope this helps
Jay
" **Developer**" <RE*************@a-znet.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
|
| > <MarshalAs(UnmanagedType.VBByRefStr)> can only be used with "InOut"
| > parameters, if you start adding InAttribute or OutAttribute to the
declare
| > statement parameters you need to give a MarshalAs with the 'regular'
| > string
| > types <MarshalAs(UnmanagedType.LPTStr)> for example, other wise you get
an
| > exception from the Marshaller.
| >
| Can't follow this. Seems to say VBByRefStr requires InOut.
| Then says In or Out requires LPTStr or something similar.
|
| What am I reading wrong?
|
|
|
| Thanks
|
|
Nov 21 '05 #8
> Hope this helps
Jay

Great answer - thanks a lot
Helps a lot
Nov 21 '05 #9

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

Similar topics

8
by: Hasani | last post by:
OK, I'm trying to programmatically create an Access database/mdb file but CreateDb(string) always returns false. I don't know what I'm doing wrong, is it my extern signature? Thx in advance ...
2
by: zDog | last post by:
I found a lot of information on passing data from C# to a C++ dll What I cannot find is a way to return C++ structs of TCHAR string data back to the C# managed code! typedef struct // C++ data...
0
by: Daniel Jin | last post by:
I'm trying to P/Invoke a method in shell32.dll. here's the method signature. LPITEMIDLIST SHBrowseForFolder( LPBROWSEINFO lpbi ); and this is the parameter structure typedef struct...
8
by: Duncan Winn | last post by:
I am new to VC++7. I am using a method GetPrivateProfileString that requires an LPTSTR. I have defined this as a: char * data_name; I am then trying to convert this to an LPOLESTR and I...
5
by: jan axelson | last post by:
My application is using RegisterDeviceNotification() to detect attachment and removal of a USB HID-class device. The form is receiving WM_DEVICECHANGE messages with wParam set to...
2
by: Tom | last post by:
I'm getting this error when I try to pass a structure to a dll. An unhandled exception of type 'System.ArgumentException' occured in Test1.exe Additional Information: Type could not be marshaled...
9
by: Gnic | last post by:
Hi, I have a (Complied) C Library that needs to be called using c# code, some of the function require char* parameter(in and out) Here is the problem, There is a function that expect an...
9
by: CapCity | last post by:
We're rewritting an app using C# 2005 and it needs to read files in netCDF format. A dll is available for this and we've had success in calling its functions, unless it updates strings. We have...
1
by: JohnCox | last post by:
I have a simple Win32 DLL I wrote named "SimpleLib" that exports two functions. It is written in C++ and compiled with __stdcall (/Gz) and with the preprocessor definition _MBCS (not Unicode). ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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,...
0
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...

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.