|
Hello to all. My first thread on this forum. I'm really new with C# and I got stuck with a pointer. I've done some research with no success.
I'm making an application that works with buffers. I have to call some C++ functions with data pointers as arguments. I'm trying to not use unsafe code.
One of the functions have two parameters of type char*. I've defined on C# two buffers:
byte[] Buffer1 = new byte[SIZE];
byte[] Buffer1 = new byte[SIZE];
On the dllimport I use marshaling:
....
[MarshalAs(UnmanagedType.LPArray)] byte[] buffer1,
[MarshalAs(UnmanagedType.LPArray)] byte[] buffer2,
....
These two buffers are filled by the C++ function.
In order to retrieve the data of the buffers, I use another C++ function. This function returns in a parameter the last buffer filled:
void FillBuff(char **Pbuff);
Pbuff is a pointer to one of the byte[] buffers defined above.
The problem is that I don't know how to define a C# to assign the pointer returned by the C++ function and accessing to the buffer's content.
Any suggestion?
Thanks in advance
|
|
|
|
|
Hi,
when mixing managed code and unmanaged/native code, I recommend you let the managed side do the array allocations (so they are real objects); doing so, all you need is one of two things:
1. the fixed keyword, which is OK if the array is used natively only while the native function executes; here the P/Invoke prototype takes a pointer where the native code expects a pointer.
2. the GCHandle class, which allows you to:
- pin the object, so the GC can no longer move it around
- get a pointer to it
- pass that pointer to the native function
- when done, free the GCHandle object.
Here the P/Invoke prototype takes an IntPtr where the native code expects a pointer.
BTW: for strings, there are easy shortcuts:
- read-only strings can be passed as string and accepted as char*
- read/write strings can be passed as StringBuilder (call ToString when done)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Thanks for answering.
They are not strings, are image buffers. I use a ping-pong strategy: One buffer for grabing image, the other for processing it, both alternating. I declare both buffers at the C# application and pass them to the C++ DLL. The image grabbing routine passes back the pointer to the buffer holding the last image grabbed. Is this parameter which I don't know how to declare and manage at the C# level. I'll like to have the pointer accessible everywhere, as I have to draw the image and process it.
C#: Buffer1 and Buffer2 and Pointer to active buffer
C++: Fills Buffer1 and Buffer2 and passes back pointer to last grabbed buffer
Using fixed keyword doesn't wrok for me, as I want to have a "global" variable. About GCHandle, I'm not sure if I'll be able to use it for using the Marshal.Copy:
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
int bytes = bmp.Width * bmp.Height;
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(PBuffer, 0, ptr, bytes); // TRANSFERING HERE THE CONTENT OF THE GRABBED BUFFER TO THE BITMAP IN ORDER TO PAINT IT
// Unlock the bits.
bmp.UnlockBits(bmpData);
Thanks in advance for helping
|
|
|
|
|
Hi,
when fixed doesn't fit the requirements, GCHandle will. I tend to almost always use GCHandle, even when fixed would suffice. One of the advantages is you typically don't need to copy the data AT ALL, since the scenario is:
1. managed world creates an array
2. uses GCHandle to pin and get the pointer
3. passes it to native world, which fills the buffer, then returns
4. managed world frees GCHandle and uses the array.
See, no copy involved, hence also no performance hit.
If the buffer is really the entire pixel data of a Bitmap, I would try and use Bitmap.Lockbits to pin and get the pointer (it does what GCHandle does for a general object), pass that pointer to the native world, and all would be OK again without a copy operation, provided your native code:
1. applies the right byte ordering within a pixel
2. applies the right pixel ordering
3. applies the right bitmap stride (normally no problem if scanlines are a multiple of 4 bytes, which is true for 32-bit pixels, or image widths that are multiples of 4).
My number 1 rule in image processing is: avoid copy operations.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hi Luc.
The problem here is that is the C++ DLL who fills the buffer. The C# application doesn't know which buffer has been filled. Is for this reason that I need to call a function to get the pointer to the buffer. It's important for me to let the native world (C++) control the flow of grabbing images on alternate buffers in order to improve the processing speed of the system (real time image processing). If I don't succeed on getting the buffer pointer I'll try another thing.
I'll keep you informed.
Thanks for your time.
|
|
|
|
|
Hi,
that is a secondary issue. Let the managed side provide one or more buffers to the native world, which fills one and tells which one. You don't need to return a pointer for that, a simple ID could do; but if you do return a pointer, keep a Dictionary that maps pointers to Bitmaps, and perform a pointer look-up.
However, if there are only two bitmaps, and you alternate them, there is no need to return anything, alternation is quite predictable!
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hi Luc.
I did why you told me about sending an Id instead of the buffer pointer. Now it's just a matter of drawing a 8 bit grey scale image on a picturebox without moving too much data.
Thanks for tips.
|
|
|
|
|
Need some direction on how to enumerate local groups and users remotely from a member server using a console app.
Most of the sample code out on the web requires you to know the names of the groups prior to executing the code and the select statements dont ever seem correct. I have used directoryentry to connect to the local servers but directorysearcher seems to always fail.
|
|
|
|
|
I have program that will input an amount of money so I do not want the user to input something like $2.684. I need to be able to count the number of decimals so I can create an if statement that prevents the user from inputting such a number.
|
|
|
|
|
Yes.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
well if you are using a textbox then you will need a number of different validations...
1. Check the currency symbol exists only once and is the first character, if not present you should auto add it
2. Check there is only 1 decimal point
3. Check for any , symbols you may want to include and insure they are in the right places
4. Check only two digits after the decimal place...
if(text.LastIndexOf('.') != text.Length - 3)
//not two digits after the decimal point
...there are other validations you may want to try and other methods to calculate the number of digits after a decimal.
you could also use a NumericUpDown control which has a property to set how many decimal places you wish to use, in addition to choosing if you want to you commas for thousand seperators
Life goes very fast. Tomorrow, today is already yesterday.
|
|
|
|
|
subtract the integer part
multiply by 100
subtract the integer part, again
if result not equal to 0 then you've got a problem.
|
|
|
|
|
Anyone familar with Dccg which is a software that work with RS232? i try to play around with this software, and hopefully can use my command to control the Motorola Set-top-box through the Dccg. So anyone has any ideas or suggest?
thanks a lot.
|
|
|
|
|
is it Dutch Colorectal Cancer Group [^] you are considering? Please formulate your question so most people can understand it; if applicable, provide a link too.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
|
Sorry about the Non-Clear statement. Again, Dccg stand for DigiCable Control Channel Generator. It is a software for RS232.
|
|
|
|
|
Sorry, I'm not familiar with that one. Google told me there is a Motorola patent, and not much else.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
I had enclosed the datagrid in a <div> element
<code><DIV style="OVERFLOW-Y: auto;</code> . . .
The horizontal scrollbar will move, but the datagrid will not scroll thru the data.
Is there a new way to do this now?
Please advise,
smcirish
Texas
|
|
|
|
|
how do i insert data into 2 dimensional byte array and send it as such over network
This code was posted by me...
|
|
|
|
|
You can't insert into arrays (not 1d arrays either), and you'd have to convert it to a 1d array to send it over the network.
|
|
|
|
|
how do i pass a byte array from one form to another form
This code was posted by me...
|
|
|
|
|
This might not be a very good method to do so, but I overload the Show method of the form being shown, so that it accepts a byte[] as an argument. I then store it in a class-level variable and call base.Show()
Between the idea
And the reality
Between the motion
And the act
Falls the Shadow
|
|
|
|
|
i want to store the processes running on a system in one string and send it as byte over network
if i do so how much a string can hold
or if i use string array will it work??
(i know how to list the process)
This code was posted by me...
|
|
|
|
|
Hi,
if you open a Socket or a NetworkStream you can send as much as you like, either in text (Unicode, ASCII, ...) or in binary (more compact, more compatibility concerns).
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
hello, i write from italy so my english is not so good: i'm sorry
i'm writing a program that should log filter based activity on my computer
i need to log when a document (doc, xls, ppt... etc)
is open, or readed, or is edited, or deleted
in my first attempt was capturing what files are open by all current open processes
for example:
winword.exe > test.doc // someone is reading a document
nero.exe > test.doc // someone is burning a document
but maybe is not a good solution
now, what do you think about this?
how i can do this job better?
hooks?
p.s. i cannot use windows event log for some reason... windows xp home and domains, etc
thank you in advance
|
|
|
|