473,378 Members | 1,037 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

pinvoke using structs

Hi,

I'm reading data from a tape device using p/invoke. It's working pretty
well, but when I'm trying to get data about the tape device, I'm doing
something wrong. I believe it has something to do with the struct I'm
passing in, but I just can't figure out what. Any help would be much
appreciated. I'm an absolute interop newbie, so please bear with me.

The Win32 API signature looks like this:

DWORD GetTapeParameters(
HANDLE hDevice,
DWORD dwOperation,
LPDWORD lpdwSize,
LPVOID lpTapeInformation
);

I've translated that into the following import signature:

[DllImport("kernel32.dll", SetLastError=true)]
static extern uint GetTapeParameters(
IntPtr hDevice, // Handle to tape device.
uint dwOperation, // Parameter type (media/drive).
out uint lpdwSize, // Size of parameter buffer.
IntPtr lpTapeInformation // Pointer to parameter struct.
);

The media parameter struct originally looks like this:

typedef struct _TAPE_GET_MEDIA_PARAMETERS {
LARGE_INTEGER Capacity;
LARGE_INTEGER Remaining;
DWORD BlockSize;
DWORD PartitionCount;
BOOLEAN WriteProtected;
} TAPE_GET_MEDIA_PARAMETERS,
* PTAPE_GET_MEDIA_PARAMETERS;

Consulting winnt.h (I've never programmed Windows pre-.NET), I found that
LARGE_INTEGER was a 64-bit signed integer, DWORD a 32-bit unsigned integer,
and BOOLEAN a single byte. So I translated the struct into the following:

[StructLayout(LayoutKind.Sequential)]
internal struct MediaParameters
{
internal Int64 Capacity;
internal Int64 Remaining;
internal UInt32 BlockSize;
internal UInt32 PartitionCount;
internal Byte WriteProtected;
}

I try to make all this work from a C# wrapper method that calls the imported
Win32 API method.

internal MediaParameters GetTapeMediaParameters()
{
// Keep object alive for the remainder of this method.
GC.KeepAlive(this);

MediaParameters param = new MediaParameters();
IntPtr paramPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(param));
Marshal.StructureToPtr(param, paramPtr, false);
uint size;
// Call imported Win32 API method to populate struct.
// 0 specifies media parameters (as opposed to drive parameters).
SystemErrorCode code = (SystemErrorCode) GetTapeParameters(_hTape, 0, out
size, paramPtr);
Debug.Assert(code == SystemErrorCode.NO_ERROR,
"Failed trying to get tape media parameters!",
"Error code: " + code.ToString());
// Should I call Marshal.PtrToStructure here?
Marshal.FreeCoTaskMem(paramPtr);
}

However, the Assert statement fails, giving me system error code 234
(ERROR_MORE_DATA).

If someone could help me, I'd be very very grateful!

Regards,
Einar

--
"If it was so, it might be; and if it were so, it would be; but as it isn't,
it ain't. That's logic" -- Lewis Carroll
Nov 16 '05 #1
2 4554
Hi,

It's not clear in msdn, but since it's probely complaining about buffer size
and you didn't specify a buffer size, you might try to do that. Change the
size parameter from out to ref. And pass the size of the struct.

uint size = Marshal.SizeOf(typeof(MediaParameters));
IntPtr paramPtr = Marshal.AllocHGlobal( size );

SystemErrorCode code =
(SystemErrorCode) GetTapeParameters(_hTape, 0, ref size, paramPtr);

Debug.Assert(code == SystemErrorCode.NO_ERROR,
"Failed trying to get tape media parameters!", "Error code: " +
code.ToString());

// Should I call Marshal.PtrToStructure here? Yes.
MediaParameters mp = (MediaParameters)Marshal.PtrToStructure( paramPtr,
typeof(MediaParameters));

Marshal.FreeHGlobal( paramPtr );

// use mp
If it still fails check the size parameter after function returns and
compare with the number of bytes in the struct.

HTH,
greetings
Nov 16 '05 #2
That solves my problem! Thanks!

Kind regards,
Einar

"BMermuys" <so*****@someone.com> wrote in message
news:t_**********************@phobos.telenet-ops.be...
Hi,

It's not clear in msdn, but since it's probely complaining about buffer size and you didn't specify a buffer size, you might try to do that. Change the size parameter from out to ref. And pass the size of the struct.

uint size = Marshal.SizeOf(typeof(MediaParameters));
IntPtr paramPtr = Marshal.AllocHGlobal( size );

SystemErrorCode code =
(SystemErrorCode) GetTapeParameters(_hTape, 0, ref size, paramPtr);

Debug.Assert(code == SystemErrorCode.NO_ERROR,
"Failed trying to get tape media parameters!", "Error code: " +
code.ToString());

// Should I call Marshal.PtrToStructure here? Yes.
MediaParameters mp = (MediaParameters)Marshal.PtrToStructure( paramPtr,
typeof(MediaParameters));

Marshal.FreeHGlobal( paramPtr );

// use mp
If it still fails check the size parameter after function returns and
compare with the number of bytes in the struct.

HTH,
greetings

Nov 16 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Carlos Guzmán Álvarez | last post by:
Hello: I'm trying to execute a function of a unmanaged dll using PInvoke, i have definied the function as: public static extern int isc_dsql_prepare( int status_vector, ref int...
2
by: markg | last post by:
Hi what is the equivalent in c# for this? Thanks typedef struct { int ID; char ProfitCenter; } REPORTSPROFITCENTERS; REPORTSPROFITCENTERS myReportsProfitCenters
1
by: Claire | last post by:
I don't understand the following error I'm getting when I call the DoOpen function of my unmanaged dll. Can someone explain please public static extern int DoOpen(ref sRDetails RDetails); ...
14
by: Bit Byte | last post by:
I have the following struct: typedef struct { string symbol; string synonym; Synonym(string _synonym, string _symbol) { synonym = _synonym; symbol = _symbol; }
1
by: CapMaster | last post by:
I've found some programs of how to create a standard game of blackjack on C++. But how would you do it using structs? Here is my assignment: Problem Statement: The purpose of this project is to...
5
by: Chris Lieb | last post by:
I am trying to create a "pseudo-class" using structs. Member variables seem easy enough to do. However, trying to implement member functions has led to nothing but frustration. I have tried...
9
by: gdarian216 | last post by:
I have written a c++ program that takes input from a file and outputs the average. The program uses structs and I need to convert the struct to a class. I just dont know how to get started and if...
7
by: Woody714 | last post by:
I'm fairly new to C++ and have an assignment that is knocking me out. The text file is fairly simple: Plain Egg 1.45 Bacon and Egg 2.45 Muffin 0.99..... etc....
4
by: quophyie | last post by:
Hi guys I''m a new C++ programmer and I am having a few problems with some structs that I have defined in my header file and want to use in my CPP file. The struct called "deck" is defined in a...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.