Marshal managed struct to native pointer

R

RYoung

Given this native struct:

typedef struct vendor
{
char name[20];
} VENDOR

I want to make managed equivalent, so I did this:

public value struct Vendor
{
public: String^ Name;
}

The managed Vendor type needs to be marshaled to void* so that an instance
of it can be passed to a native function (in the BerkeleyDB API):

Vendor^ vendor = gcnew Vendor();
vendor->Name = "Ron";

IntPtr vendorptr = Marshal::AllocHGlobal(Marshal::SizeOf(Vendor));
Marshall::StructureToPtr( vendor, vendorptr, false );
mydb.put( NULL, &key, &vendorptr, 0 );
Marshal::FreeHGlobal(vendorptr);

The "mydb.put()" method writes data to a file in a format used by
BerkeleyDB.

Note that an example application using the C-style structure above allows me
to write and read data to that file.

When I try using my managed structure, I can write but the read fails. This
leads me to believe that I need to define my structure differently (?)

Any comments on that question and the code is appreciated.

Ron
 
R

RYoung

Just wanted to correct a portion of code I posted below:
Marshall::StructureToPtr( vendor, vendorptr, false );
mydb.put( NULL, &key, &vendorptr, 0 );

- corrected here
Marshal:StructureToPtr(vendor, vendorptr, false);

Dbt data( vendorptr.ToPointer(), sizeof(Vendor));
mydb.put(NULL, &key, &data, 0);

the signature for Dbt constructor, and Db.put() is:

Dbt( void* ptr, u_int32_t size );
Db::put( DbTxn* txn, Dbt* key, Dbt* data, u_int32_t flags);

Ron

RYoung said:
Given this native struct:

typedef struct vendor
{
char name[20];
} VENDOR

I want to make managed equivalent, so I did this:

public value struct Vendor
{
public: String^ Name;
}

The managed Vendor type needs to be marshaled to void* so that an instance
of it can be passed to a native function (in the BerkeleyDB API):

Vendor^ vendor = gcnew Vendor();
vendor->Name = "Ron";

IntPtr vendorptr = Marshal::AllocHGlobal(Marshal::SizeOf(Vendor));
Marshall::StructureToPtr( vendor, vendorptr, false );
mydb.put( NULL, &key, &vendorptr, 0 );
Marshal::FreeHGlobal(vendorptr);

The "mydb.put()" method writes data to a file in a format used by
BerkeleyDB.

Note that an example application using the C-style structure above allows
me to write and read data to that file.

When I try using my managed structure, I can write but the read fails.
This leads me to believe that I need to define my structure differently
(?)

Any comments on that question and the code is appreciated.

Ron
 
B

Bruno van Dooren

RYoung said:
Just wanted to correct a portion of code I posted below:

From MSDN2:
StructureToPtr copies the contents of structure to the pre-allocated block
of memory pointed to by the ptr parameter.

This means that whatever you do with the vendorptr is irrelevant from the
managed structure 's point of view.
a read function that changes your unmanaged block of memory does not change
your managed structure.
Did you check your unmanaged ptr to see if that changed?

Btw: Is there a reason your string is a struct member, instead of just a
string?

Check out the different articles in MSDN2 on string marshalling. using the
ref keyword will allow you to read back data.
there are a number of articles on codeproject too. one of them is this:
http://www.codeproject.com/netcf/compframe2.asp#strings

--

Kind regards,
Bruno.
(e-mail address removed)
Remove only "_nos_pam"
 

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

Top