DllImport win32 and out string buffer parameters

  • Thread starter Thread starter Zytan
  • Start date Start date
Z

Zytan

When using DllImport to import win32 functions that have strings, I
know you can use the native c# string type. But, what about a
function that expects a string buffer, and writes to it? I've seen
people use StringBuilder for this, but is string good enough?

The problem is that I am seeing what appears to be uninitialized data
when I use StringBuilder, so I am wonder what is the correct solution

thanks
Zytan
 
Zytan,

You use StringBuilder when you expect the buffer to be written to, as
instances of the String class is are immutable. It wouldn't be very good to
declare instances of a class immutable and then allow something to change
it, would it? =)

The general pattern for using a StringBuilder is to intialize the buffer
in the StringBuilder to the size you need, and then pass the StringBuilder
for the parameter (of course, the P/Invoke declaration has to have a
StringBuilder type as well).
 
Are you trying to get the name of a module in another process? If not,
then this doesn't apply.

What API are you trying to use and what is the declaration that you are
using and what exactly are you trying to do?
 
Further info:

http://www.cs.bgsu.edu/drhutch/otherinfo/appnamefromhwnd.html
"The problem is that the API function GetWindowModuleFileName oddly
does not return the module file name for the given hwnd. Most of the
time it either returns the foreground module name or a blank string.
Drat!"

This is exaclty what I see, too. It was quite confusing, but the
results were so consistent, that I thought it must be by design.

Zytan
 
Are you trying to get the name of a module in another process? If not,
then this doesn't apply.

Yes.

What do you mean 'this doesn't apply'?
What API are you trying to use and what is the declaration that you are
using and what exactly are you trying to do?

I was using GetWindowModuleFileName with StringBuilder for the out
parameters, and i thought the error was due to StringBuilder, but it
was simply GetWindowModuleFileName not working. Strange that this is
NOT documented in MSDN!

Zytan
 
You use StringBuilder when you expect the buffer to be written to, as
instances of the String class is are immutable. It wouldn't be very good to
declare instances of a class immutable and then allow something to change
it, would it? =)

Right! :)
The general pattern for using a StringBuilder is to intialize the buffer
in the StringBuilder to the size you need, and then pass the StringBuilder
for the parameter (of course, the P/Invoke declaration has to have a
StringBuilder type as well).

Yup, that's just what I do. I initialize StringBuilder's buffer to a
certain size, and the win32 function that writes to it wants to know
this size, so I pass it in as well as the StringBuilder.

(I noted that it doesn't work with the "out" qualifier, because it is
not an "out" parameter, since you have to initialize it first, and the
function expects that. It was a little confusing at first. And it
doesn't help when the win32 function I'm trying to use plain doesn't
work)

Thanks, Nicholas
Zytan
 
It doesn't apply if you were looking for the name of a module in the
same process.

The knowledge base article says that this applies to Windows NT 4.0 and
Windows 2000 (and subsequently XP and other versions beyond that). It's not
that this is broken, it's that this is the defined functionality in those
operating systems.

It also suggests that you use GetModuleFileNameEx and GetModuleBaseName
in the Process Status Helper set of APIs if you need this functionality
instead.
 
(I noted that it doesn't work with the "out" qualifier, because it is
not an "out" parameter, since you have to initialize it first, and the
function expects that. It was a little confusing at first. And it
doesn't help when the win32 function I'm trying to use plain doesn't
work)

That would be because "out" is similar to "ref", which indicates a
pointer.

Zytan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top