473,799 Members | 3,298 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Does String mashal default to UnmanagedType.L PTStr

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.dl l" (ByVal hWnd
As Integer, _

ByVal nFolder As Integer, ByVal nToken As Integer, _

ByVal dwFlags As Integer, _

<MarshalAs(Unma nagedType.LPTSt r)> ByVal lpszPath As String) As Boolean

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

Public Declare Auto Function SHGetFolderPath Lib "shell32.dl l" (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.L PTStr so UnmanagedType.L PTStr need not be included??

This is how it's used:

Dim lPath As String = Space(260)

If Library.Shell.S HGetFolderPath( 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 5774
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.Environm ent.GetFolderPa th?

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

--
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******@YOUKN OWTHEDRILLcomca st.net> wrote in message
news:uF******** ******@TK2MSFTN GP12.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.Environm ent.GetFolderPa th?

--
Tom Shelton [MVP]

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

Dim lPath As New System.Text.Str ingBuilder(Libr ary.Kernel.MAX_ PATH)

'Dim lPath As String = Space(260)

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

" **Developer**" <RE************ *@a-znet.com> wrote in message
news:eh******** ******@tk2msftn gp13.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******@YOUKN OWTHEDRILLcomca st.net> wrote in message
news:uF******** ******@TK2MSFTN GP12.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.Environm ent.GetFolderPa th?

--
Tom Shelton [MVP]


Nov 21 '05 #5
**Developer**
In addition to the other comments, the default for VB.NET is
UnmanagedType.V BByRefStr, 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(Unma nagedType.VBByR efStr)> 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(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.

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

Hope this helps
Jay
" **Developer**" <RE************ *@a-znet.com> wrote in message
news:OY******** ******@TK2MSFTN GP14.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.dl l" (ByVal hWnd
| As Integer, _
|
| ByVal nFolder As Integer, ByVal nToken As Integer, _
|
| ByVal dwFlags As Integer, _
|
| <MarshalAs(Unma nagedType.LPTSt r)> ByVal lpszPath As String) As Boolean
|
|
|
| Tried this because I saw some place (not in the doc) that
| UnmanagedType.L PTStr was the default for String. This works too.
|
| Public Declare Auto Function SHGetFolderPath Lib "shell32.dl l" (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.L PTStr so UnmanagedType.L PTStr need not be included??
|
|
|
| This is how it's used:
|
| Dim lPath As String = Space(260)
|
| If Library.Shell.S HGetFolderPath( 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(Unma nagedType.VBByR efStr)> 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(Unma nagedType.LPTSt r)> 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.dl l" ( _
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 Interoperabilit y 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******** ********@tk2msf tngp13.phx.gbl. ..
|
| > <MarshalAs(Unma nagedType.VBByR efStr)> 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(Unma nagedType.LPTSt r)> 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
1550
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 my references: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_data_source.3a_.programmatically_configuring_an_odbc_data_source.asp ...
2
11640
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 that needs to be returned to the caller (C#) { short snOperParams; TCHAR szNFPath; TCHAR szSSFile; TCHAR szExeFile;
0
1202
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 _browseinfo { HWND hwndOwner; LPCITEMIDLIST pidlRoot; LPTSTR pszDisplayName;
8
4348
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 have done this as follows: LPOLESTR dunk_data = (LPOLESTR)T2CW(data_name);
5
7741
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 DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE. I want to identify the device that has arrived or been removed by examining the dbcc_name member of the DEV_BROADCAST_DEVICEINTERFACE structure.
2
5073
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 because the length of an embedded array instance does not match the declared length in the layout What does it mean?
9
20374
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 input char* parameter for example
9
3522
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 tried several of the suggestions we've found on-line: Strings, StringBuilders, IntPtr, etc., but haven't been able to exactly pull it off. What seem to be closest is the following. It's a function that will return a variable name for a given file...
1
2775
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). The first function is called "StrFirst" and takes in a LPTSTR as the first parameter and a long as the second, like this: SIMPLELIB_API int StrFirst(LPTSTR str, long num); The second function is essentially the same thing, but with the order of the...
0
9688
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9546
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
10490
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
10030
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
9078
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
6809
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
5467
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
5590
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4146
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.