471,305 Members | 1,105 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

Getting updated string from unmanaged DLL

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 ID and variable ID. We first have this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);

The status comes back as 0, which is a success. varName.ToString() gives us
"????m????????9" but we know the name to be "TEMP_1p5m". The file has a
another variable, TFLAG, but using that varID gives back a variable name of
"??G??????????9".

Both returned values are the same length. And oddly enough, the "m" in the
first one, and the "G" in the second one, are recognizable in the known
values. And if each of the leading "?" were to represent 2 characters of the
known value then the "m" and "G" are in the right place.

Any thoughts on how to get the string value correctly?
Jan 4 '07 #1
9 3402
CapCity wrote:
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 ID and variable ID. We first have this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);

The status comes back as 0, which is a success. varName.ToString() gives us
"????m????????9" but we know the name to be "TEMP_1p5m". The file has a
another variable, TFLAG, but using that varID gives back a variable name of
"??G??????????9".

Both returned values are the same length. And oddly enough, the "m" in the
first one, and the "G" in the second one, are recognizable in the known
values. And if each of the leading "?" were to represent 2 characters of the
known value then the "m" and "G" are in the right place.

Any thoughts on how to get the string value correctly?

More like an encoding issue to me.

tried all other options than Unicode - same result

What options you have tried, if you can list all the options you tired,
people here may be able to help you.

And what's the byte value of those ?, are they same ??

John
Jan 4 '07 #2
On Thu, 4 Jan 2007 07:21:10 -0500, "CapCity" <sgomori at yahoo dot
comwrote:
>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 ID and variable ID. We first have this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
Unicode covers a multitude of sins. Have you tried being more
specific: ASCII, UTF7, UTF8? EBCDIC would be a long shot I suspect.
>public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);
Have you tried char[]? For disgnostic purposes you might also want to
try passing in a byte[] and have a look at what comes back as hex -
that might give you a better idea of what the dll is actually
returning.
>
The status comes back as 0, which is a success. varName.ToString() gives us
"????m????????9" but we know the name to be "TEMP_1p5m". The file has a
another variable, TFLAG, but using that varID gives back a variable name of
"??G??????????9".
Try converting the return directly to a byte array to see what is
actually in there before you start trying to convert it. After
conversion you are seeing a mix of the return and the conversion
function. You need to start by looking just at the return from the
dll. Once you know exactly what is going into the conversion function
should you have a look at what is coming out of it.
>
Both returned values are the same length. And oddly enough, the "m" in the
first one, and the "G" in the second one, are recognizable in the known
values. And if each of the leading "?" were to represent 2 characters of the
known value then the "m" and "G" are in the right place.
This may mean that there is UTF16 in there somewhere. UTF16 uses two
bytes per character rather than one byte for UTF7, UTF8 or ASCII. The
same length may just be due to overflow protection preventing writing
off the end of an array or string.

rossum
>
Any thoughts on how to get the string value correctly?
Jan 4 '07 #3

"Jianwei Sun" <js***********@gmail.comwrote in message
news:Oi**************@TK2MSFTNGP02.phx.gbl...
CapCity wrote:
>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 ID and variable ID. We first have
this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);

The status comes back as 0, which is a success. varName.ToString() gives
us "????m????????9" but we know the name to be "TEMP_1p5m". The file has
a another variable, TFLAG, but using that varID gives back a variable
name of "??G??????????9".

Both returned values are the same length. And oddly enough, the "m" in
the first one, and the "G" in the second one, are recognizable in the
known values. And if each of the leading "?" were to represent 2
characters of the known value then the "m" and "G" are in the right
place.

Any thoughts on how to get the string value correctly?

More like an encoding issue to me.

tried all other options than Unicode - same result

What options you have tried, if you can list all the options you tired,
people here may be able to help you.
The options are Ansi, Auto, None and Unicode
>
And what's the byte value of those ?, are they same ??
The byte values of each of those is 63, the ascii code for "?"
>
John

Jan 4 '07 #4

"rossum" <ro******@coldmail.comwrote in message
news:p4********************************@4ax.com...
On Thu, 4 Jan 2007 07:21:10 -0500, "CapCity" <sgomori at yahoo dot
comwrote:
>>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 ID and variable ID. We first have this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
Unicode covers a multitude of sins. Have you tried being more
specific: ASCII, UTF7, UTF8? EBCDIC would be a long shot I suspect.
>>public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);
Have you tried char[]? For disgnostic purposes you might also want to
try passing in a byte[] and have a look at what comes back as hex -
that might give you a better idea of what the dll is actually
returning.
>>
The status comes back as 0, which is a success. varName.ToString() gives
us
"????m????????9" but we know the name to be "TEMP_1p5m". The file has a
another variable, TFLAG, but using that varID gives back a variable name
of
"??G??????????9".
Try converting the return directly to a byte array to see what is
actually in there before you start trying to convert it. After
conversion you are seeing a mix of the return and the conversion
function. You need to start by looking just at the return from the
dll. Once you know exactly what is going into the conversion function
should you have a look at what is coming out of it.
The byte values for those ? are 63, so they're actual ? and not just
something to represent something unprintable
>>
Both returned values are the same length. And oddly enough, the "m" in the
first one, and the "G" in the second one, are recognizable in the known
values. And if each of the leading "?" were to represent 2 characters of
the
known value then the "m" and "G" are in the right place.
This may mean that there is UTF16 in there somewhere. UTF16 uses two
bytes per character rather than one byte for UTF7, UTF8 or ASCII. The
same length may just be due to overflow protection preventing writing
off the end of an array or string.

rossum
>>
Any thoughts on how to get the string value correctly?

Jan 4 '07 #5

"CapCity" <sgomori at yahoo dot comwrote in message
news:uX**************@TK2MSFTNGP06.phx.gbl...
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 ID and variable ID. We first have this:

[DllImport("netcdf.dll", CharSet = CharSet.Unicode)] //Also have
tried all other options than Unicode - same result
public static extern int nc_inq_varname(int ncid, int varid,
[Out,MarshalAs(UnmanagedType.LPTStr)] StringBuilder varName);

Then the call:
StringBuilder varName = new StringBuilder(100);
int status = nc_inq_varname(NCID, varID, varName);

The status comes back as 0, which is a success. varName.ToString() gives
us "????m????????9" but we know the name to be "TEMP_1p5m". The file has a
another variable, TFLAG, but using that varID gives back a variable name
of "??G??????????9".

Both returned values are the same length. And oddly enough, the "m" in the
first one, and the "G" in the second one, are recognizable in the known
values. And if each of the leading "?" were to represent 2 characters of
the known value then the "m" and "G" are in the right place.

Any thoughts on how to get the string value correctly?
Thanks to all who put thought into this. The solution to the above was to
have LPStr as the MarshalAs type, not LPTStr.
Now we're fighting with another function in the same DLL. The signature is:

int nc_get_var_float (int ncid, int varid, float *fp). We're looking to see
what we can use in C# to hold the array of floats. Just using an array of
floats gives some error code that MS says can be fixed by installing SP2 for
Win 2000 (we're running XP).

Jan 4 '07 #6
>Now we're fighting with another function in the same DLL. The signature is:
>
int nc_get_var_float (int ncid, int varid, float *fp). We're looking to see
what we can use in C# to hold the array of floats. Just using an array of
floats gives some error code that MS says can be fixed by installing SP2 for
Win 2000 (we're running XP).
A float[] should work fine. Can you post your declaration, calling
code and details on the error you get?
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Jan 4 '07 #7

"Mattias Sjögren" <ma********************@mvps.orgwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
Now we're fighting with another function in the same DLL. The signature
is:

int nc_get_var_float (int ncid, int varid, float *fp). We're looking to
see
what we can use in C# to hold the array of floats. Just using an array of
floats gives some error code that MS says can be fixed by installing SP2
for
Win 2000 (we're running XP).

A float[] should work fine. Can you post your declaration, calling
code and details on the error you get?
Absolutely.
The documentation that came with the DLL has the signature as this:

int nc_get_var_float (int ncid, int varid, float *fp).

Our declaration is:

[DllImport("netcdf.dll")]
public static extern int nc_get_var_float(int ncid, int varid, ref float[]
fValues);
The call is this:

float[] fValues = { 0.0F }; //Build error if this array is not
initialized
status = nc_get_var_float(NCID, varID, ref fValues);

And the message we get on the call is:

The program '[496] EPAWA41_Dev2.vshost.exe: Managed' has exited with
code -1073741819 (0xc0000005).

We tried to add some marshalling to the declaration, but got a pop-up
'FatalExecutionEngineError'.

>
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jan 5 '07 #8
>Our declaration is:
>
[DllImport("netcdf.dll")]
public static extern int nc_get_var_float(int ncid, int varid, ref float[]
fValues);
Try it without the ref modifier.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Jan 5 '07 #9

"Mattias Sjögren" <ma********************@mvps.orgwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
Our declaration is:

[DllImport("netcdf.dll")]
public static extern int nc_get_var_float(int ncid, int varid, ref float[]
fValues);

Try it without the ref modifier.
That worked! I also had to declare the array with a fixed size, but it is
known ahead of time, so that's not too big of a deal. I think the last is a
"feature" with the DLL and not really a rule of thumb. The "ref" thing makes
sense now that you pointed it out.

Anyway - thank you!
>
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jan 5 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by rasa | last post: by
4 posts views Thread by quat | last post: by
7 posts views Thread by Søren Dreijer | last post: by
15 posts views Thread by Mark C | last post: by
10 posts views Thread by Mike | last post: by

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.