473,405 Members | 2,154 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,405 software developers and data experts.

From int[] to IntPtr and back

Hi,

I am having a bit of trouble with some pinvoke signatures. The orginal
API call takes a pointer to a array. Of course when imported into C# it
takes an IntPtr.

Now, how do I get a int[] instance converted to an IntPtr?

And back again...

--
Thomas Due
Posted with XanaNews version 1.17.6.4

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu
Nov 17 '05 #1
7 21716
I am tracking a similar problem, I recommend you try

InPtr myPtr = Pointer.Box(ArrayName,typeof(int *));

"Thomas Due" wrote:
Hi,

I am having a bit of trouble with some pinvoke signatures. The orginal
API call takes a pointer to a array. Of course when imported into C# it
takes an IntPtr.

Now, how do I get a int[] instance converted to an IntPtr?

And back again...

--
Thomas Due
Posted with XanaNews version 1.17.6.4

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu

Nov 17 '05 #2
Thomas,

Can you post the original API signature? I recommend declaring the API
in C# using an array. That way the interop marshaler will either copy
or pin the data for you. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(int[] dst, int[] src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
CopyMemory(dst, src, src.Length * Marshal.SizeOf(typeof(int)));
}

If you choose to keep IntPtr in the signature then you'll need to pin
the array manually. You can do that by using GCHandle. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr dst, IntPtr src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
GCHandle psrc = GCHandle.Alloc(psrc, GCHandleType.Pinned);
GCHandle pdst = GCHandle.Alloc(pdst, GCHandleType.Pinned);
CopyMemory(
pdst.AddrOfPinnedObject(),
psrc.AddrOfPinnedObject(),
src.Length * Marshal.SizeOf(typeof(int)));
pdst.Free();
psrc.Free();
}

As you can see, the first example is easier.

Brian

Thomas Due wrote:
Hi,

I am having a bit of trouble with some pinvoke signatures. The orginal
API call takes a pointer to a array. Of course when imported into C# it
takes an IntPtr.

Now, how do I get a int[] instance converted to an IntPtr?

And back again...

--
Thomas Due
Posted with XanaNews version 1.17.6.4

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu


Nov 17 '05 #3
Why use the CopyMemory while Array.Copy does the same thing through a single
managed API call?

Willy.

"Brian Gideon" <br*********@yahoo.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Thomas,

Can you post the original API signature? I recommend declaring the API
in C# using an array. That way the interop marshaler will either copy
or pin the data for you. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(int[] dst, int[] src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
CopyMemory(dst, src, src.Length * Marshal.SizeOf(typeof(int)));
}

If you choose to keep IntPtr in the signature then you'll need to pin
the array manually. You can do that by using GCHandle. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr dst, IntPtr src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
GCHandle psrc = GCHandle.Alloc(psrc, GCHandleType.Pinned);
GCHandle pdst = GCHandle.Alloc(pdst, GCHandleType.Pinned);
CopyMemory(
pdst.AddrOfPinnedObject(),
psrc.AddrOfPinnedObject(),
src.Length * Marshal.SizeOf(typeof(int)));
pdst.Free();
psrc.Free();
}

As you can see, the first example is easier.

Brian

Thomas Due wrote:
Hi,

I am having a bit of trouble with some pinvoke signatures. The orginal
API call takes a pointer to a array. Of course when imported into C# it
takes an IntPtr.

Now, how do I get a int[] instance converted to an IntPtr?

And back again...

--
Thomas Due
Posted with XanaNews version 1.17.6.4

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu

Nov 17 '05 #4
Without knowing exactly which API the OP was speaking of that was the
best example I could come up with to demonstrate the different ways of
declaring and using an API in C#. More specifically, I was hoping to
convince to the OP that declaring the API with int[] instead of IntPtr
would be easier. You are correct though, perhaps I should have chosen
something a little more realistic.

Brian

Willy Denoyette [MVP] wrote:
Why use the CopyMemory while Array.Copy does the same thing through a single
managed API call?

Willy.

"Brian Gideon" <br*********@yahoo.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Thomas,

Can you post the original API signature? I recommend declaring the API
in C# using an array. That way the interop marshaler will either copy
or pin the data for you. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(int[] dst, int[] src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
CopyMemory(dst, src, src.Length * Marshal.SizeOf(typeof(int)));
}

If you choose to keep IntPtr in the signature then you'll need to pin
the array manually. You can do that by using GCHandle. For example:

[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr dst, IntPtr src, int len);

public void Foo()
{
int[] src = new int[] { 1, 2, 3, 4, 5 };
int[] dst = new int[source.Length];
GCHandle psrc = GCHandle.Alloc(psrc, GCHandleType.Pinned);
GCHandle pdst = GCHandle.Alloc(pdst, GCHandleType.Pinned);
CopyMemory(
pdst.AddrOfPinnedObject(),
psrc.AddrOfPinnedObject(),
src.Length * Marshal.SizeOf(typeof(int)));
pdst.Free();
psrc.Free();
}

As you can see, the first example is easier.

Brian

Thomas Due wrote:
Hi,

I am having a bit of trouble with some pinvoke signatures. The orginal
API call takes a pointer to a array. Of course when imported into C# it
takes an IntPtr.

Now, how do I get a int[] instance converted to an IntPtr?

And back again...

--
Thomas Due
Posted with XanaNews version 1.17.6.4

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu


Nov 17 '05 #5

"Brian Gideon" <br*********@yahoo.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
Without knowing exactly which API the OP was speaking of that was the
best example I could come up with to demonstrate the different ways of
declaring and using an API in C#. More specifically, I was hoping to
convince to the OP that declaring the API with int[] instead of IntPtr
would be easier. You are correct though, perhaps I should have chosen
something a little more realistic.

Brian


I see, you are correct the OP could remove the guesswork by posting the API
he's speaking of.

Willy.
Nov 17 '05 #6
Willy Denoyette [MVP] wrote:
I see, you are correct the OP could remove the guesswork by posting
the API he's speaking of.


Of course, my bad. It is the DeviceIOControl in kernel32.dll, according
to Win32SDK help, it is declared like this:

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

According to www.pinvoke.net, this is "translated" to:

[DllImport("kernel32.dll", ExactSpelling = true,
SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
--
Thomas Due
Posted with XanaNews version 1.17.6.5

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu
Nov 17 '05 #7
Thomas,

Try the following:

[DllImport("kernel32.dll")]
public static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
byte[] lpInBuffer,
uint nInBufferSize,
byte[] lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);

You can declare other overloads that accept int arrays instead of byte
arrays as well. The lpOverlapped parameter is really a pointer to the
OVERLAPPED structure. If you don't plan on using overlapped operations
I'd leave it as an IntPtr and just pass in IntPtr.Zero when called.

Brian

Thomas Due wrote:
Willy Denoyette [MVP] wrote:
I see, you are correct the OP could remove the guesswork by posting
the API he's speaking of.


Of course, my bad. It is the DeviceIOControl in kernel32.dll, according
to Win32SDK help, it is declared like this:

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

According to www.pinvoke.net, this is "translated" to:

[DllImport("kernel32.dll", ExactSpelling = true,
SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
--
Thomas Due
Posted with XanaNews version 1.17.6.5

"To fight and conquer in all your battles is not supreme excellence;
supreme excellence consists in breaking the enemy's resistance without
fighting."
-- Sun-Tzu


Nov 17 '05 #8

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

Similar topics

14
by: Pranab Mehta | last post by:
Hi All, I apologize if this has been brought up here before. Searching through the newsgroup I found variants of my question, but not exactly what I am thinking about. If on a given platform,...
1
by: Gary | last post by:
I have a strange compile error. C2664 cannot convert parameter 2 from int to int... Earlier in my code I was setting up my dataset... I add an int field like so... ...
24
by: pinkfloydhomer | last post by:
Is it well-defined to make a cast from a pointer to an int and back? Like: typedef struct { int whatever; } S; int main(void) {
2
by: Ulrich Hobelmann | last post by:
Hi, I admit that this isn't great C++, but I'm reusing a container class I wrote in C, which stores void * elements. Sometimes I insert pointers into the container, sometimes ints (both are 32bit...
6
by: Angus | last post by:
I am using a global which is a void* I have it defined in one file as: void* hFlag; and one other header file as: extern void* hFlag; But I get this compile error:
3
by: fazulu deen | last post by:
Hi all, For the following code : file_ptr = fopen("pass_fail.txt", "a"); // error line 393 fdisplay(file_ptr, "Test Passed"); fclose(file_ptr);
7
by: mng2nf | last post by:
i'm having problems with this portion of code... the entire program is an invoice for a carpet installation asking for the room dimensions and various rates and amounts to calculate how much to...
1
by: Nozdormu | last post by:
Hi guys, I have a quick question. The language I'm using is C. The question I'm tackling: Write a program that (1) defines a 1D array with ten int elements, and (2) sets the values of the...
2
by: kenneth6 | last post by:
int a=10; int b=3; float c; c=a/b; cout << c << endl; if, in my program, the int type for a and b is a must (according to the return), performing operation on a & b results in float type...
5
by: rtrujillor | last post by:
int iAnno = 2005; int iMes = 7; int iDia = 23; std::stringstream ssAnno; ssAnno << iAnno; std::string anno = ssAnno.str(); std::stringstream ssMes; ssMes << iMes;
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.