471,305 Members | 1,311 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.

interop c dll import function returns a structure containing strings

Q: How do you return a LPSTR from unmanaged code?
A: Use a StringBuilder.

What about this:
public struct CSTRUCT {
string return_value;

How do you get a LPSTR from unmanaged code when it is in a STRUCT?

Read on for more detail.....


I have been getting up to speed on C# Interop the last few days.

I have a program that works fairly well in C++ but I want to port it to
C# because I am more comfortable with C#.

Here is a sample of the struct I am working with: (the actual structure
is much larger).

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=2 )]
public struct CSTRUCT
public uint prev; /* PREVIOUS */
public uint curr; /* CURRENT record pointers */
public uint next; /* NEXT */
public short list_type;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=34 )]
public string input_data;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=34 )]
public string return_data;

I pass this to a function defined like so (assume that some fields in
CSTRUCT are for internal use by the API. In this example, input_data is
a string that I need to assign a value to for the work to be done

[ DllImport( "oldc.dll", CharSet=CharSet.Ansi )]
public static extern int doWork(int a_number, ref CSTRUCT a_record);

Then I wait for the dll to raise an event. I need to call another
function to determine if doWork succeeded and what the contents of
a_record.return_data is.

[ DllImport( "oldc.dll", CharSet=CharSet.Ansi )]
public static extern int workDone(ref EVENT an_event, out CSTRUCT

Note that the API in oldc.dll maintains an internal copy of a_record.
When workDone is called, you pass in an initialised CSTRUCT variable
and workDone fills in the return_data member. (an_event is a structure
which tells the api which record to return).

My problem is this:
The code compiles (not yet, keep reading)
CLR does not raise an exception (whew! should be okay, right?)
Oops, a_record is not updated by the function call (does anybody sense

If I do a debug trace on the C++ code in my other project, I can see
that the structure contains unintialised data before the function call,
then afterward, return_data is correctly populated.

When I do a similar debug trace in C#, the struct is initialised to
null values (0 for integral types, "" for string types) before the
function call, and is the same after the function call.
If I do not destroy a_record after the call to doWork, and pass that to
workDone, in this case the data also is not changed, eg, input_data is
still populated, but return_value has not changed. Is this the standard
behaviour for .Net? Is there another way to accomplish this?

Things tried: changing updated_record from "out" to "ref" - no change.
Changing "ref CSTRUCT" to "CSTRUCT" (and making CSTRUCT a class instead
of a struct) - no change.
Examining the int return value from workDone - the return value
indicates that the function succeeded.
Changing "out CSTRUCT" to "byte[]" where the byte array is initialised
to the same size as CSTRUCT - after the function call, the byte array
is unchanged, eg all items are 0. (I tried this on the doWork function
and the data was passed in correctly.)

1) Go back to c++ and create a separate application
2) Go back to c++, create a wrapper of some kind (dll) that I call from
C#. C++ gets the returned struct, then passes back the string values
individually to C#.



Feb 7 '06 #1
0 2011

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Penn Markham | last post: by
3 posts views Thread by Jon Skeet | last post: by
2 posts views Thread by Frank | last post: by
reply views Thread by Andrew S. Giles | last post: by
1 post views Thread by ivang | 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.