Re: C# - getting binary data from .lib
- From: "Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx>
- Date: Sat, 3 Jun 2006 17:03:39 -0400
Looking at your original requirements, you have a second choice. You may
use the Marshal class to allocate the number of bytes that you need for the
image array.
Use Marshal.AllocHGlobal to allocate the memory and pass this IntPtr to the
wrapper as I described in my previous post.
You must change your wrapper to the following:
WIN32DLL_API int create_wrapped(int id, int scale, void** image)
{
unsigned char* ptrImage = (unsigned char*)GlobalLock(*image);
int retCode = create(id, scale, ptrImage);
GlobalUnlock(*image);
return retCode;
}
You now control the pointer returned. Use the Marshal class to read or copy
the bytes and use Marshal.FreeHGlobal to free the memory for the unmanaged
pointer.
To make things more general you can test to see if the pointer is null to
begin with and use one wrapper that will work with unallocated memory or
allocate memory as follows:
WIN32DLL_API int create_wrapped(int id, int scale, void** image)
{
int retCode = -1;
unsigned char* ptrImage = NULL;
if ( NULL != *image )
{
ptrImage = (unsigned char*)GlobalLock(*image);
retCode = create(id, scale, ptrImage);
GlobalUnlock(*image);
}
else
{
retCode = create(id, scale, ptrImage);
*image = (void*)ptrImage;
}
return retCode;
}
"Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx> wrote in message
news:OqJ0530hGHA.1324@xxxxxxxxxxxxxxxxxxxxxxx
label1.Text = create_wrapped(0,5,ref ptrImage).ToString();
The above line is not correct! You cannot assign binary image data to
Text as the types are not compatible.
If there was no error, then the value of ptrImage will not be equal to
IntPtr.Zero.
You may use the Marshal class to copy or read the image bytes to a managed
C# byte array that you allocate.
Remember the wrapper is returning an unmanaged pointer to an array of
bytes. You need to convert this to a managed pointer of the same type.
Additionally, you have to worry about disposing of the memory allocated
for the unmanaged pointer. On the C# side your pointer is garbage
collected automatically.
"Stephen Cawood" <cawood@xxxxxxxxxx> wrote in message
news:sbmgg.24496$JX1.10537@xxxxxxxxxxx
thanks again. I'm reluctant to try and deal with the unmanaged pointer
since I'm getting an error back from the function.
label1.Text = create_wrapped(0,5,ref ptrImage).ToString();
// returned -1 meaning that there was a problem
any ideas why this is returning a failure message? when I used byte[]
image as the argument, I got back success message (0)... and an empty
array :)
"Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx> wrote in message
news:ujJsSm0hGHA.412@xxxxxxxxxxxxxxxxxxxxxxx
I am sorry that was a typo. Use (unsigned char*) rather than (char*).
What you are trying to accomplish is to let the wrapper internally call
the library to allocate memory for the image when a null pointer is
passed as an argument.
The library should return the pointer to this allocated memory. In "C",
this is accomplished by passing a pointer to a pointer on the stack.
In C# you are passing the address to a null pointer. You should get
back an unmanaged pointer with the allocated image.
"Stephen Cawood" <cawood@xxxxxxxxxx> wrote in message
news:4nlgg.24072$JX1.915@xxxxxxxxxxx
BTW - the binary data is used to create .PGM image files.
"Stephen Cawood" <cawood@xxxxxxxxxx> wrote in message
news:nhlgg.24033$JX1.23566@xxxxxxxxxxx
thanks again, I really appreciate the help. this problem has been a
real pain.
I tried your suggestion, but it didn't work. however, I feel that I
might be very close.
label1.Text = create_wrapped(0,5,ref ptrImage).ToString();
// returned -1 meaning that there was a problem
my original wrapper function was:
WIN32DLL_API int create_wrapped(int id, int scale, unsigned char
*image)
{
return create(id, scale, image);
}
so I tried changing that to:
WIN32DLL_API int create_wrapped(int id, int scale, void** image)
{
return create(id, scale, (unsigned char*)*image);
}
your suggestion wouldn't compile:
WIN32DLL_API int create_wrapped(int id, int scale, void** image)
{
return create(id, scale, (char*)*image);
}
the error was: Cannot convert argument 3 from char* to unsigned char*
"Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx> wrote in message
news:%23EGjMdzhGHA.1508@xxxxxxxxxxxxxxxxxxxxxxx
Your wrapper function should have the argument typed as a pointer to
a pointer for this to work correctly.
[DllImport("Wrapper.dll", EntryPoint="create_wrapped")]
public static extern int create_wrapped(int id, int scale, [In][Out]
ref
IntPtr image);
WIN32DLL_API int create_wrapped(int id, int scale, void** image)
{
return create(id, scale, (char*)*image);
}
You call it as follows:
IntPtr ptrImage = IntPtr.Zero;
label1.Text = create_wrapped(0,5,ref ptrImage);
and of course check for a null pointer return.
"Stephen Cawood" <cawood@xxxxxxxxxx> wrote in message
news:o1jgg.23800$JX1.19291@xxxxxxxxxxx
I thought that you might be on to something, but sadly it didn't
work.
thanks for the help though.
[DllImport("Wrapper.dll", EntryPoint="create_wrapped")]
public static extern int create_wrapped(int id, int scale, [In][Out]
ref IntPtr image);
IntPtr ptrImage = new IntPtr();
label1.Text = create_wrapped(0,5,ref ptrImage).ToString(); //this
crashes the debugger with no exception returned, I tried to catch it
but that didn't help
"Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx> wrote in
message news:uJyWUbyhGHA.4044@xxxxxxxxxxxxxxxxxxxxxxx
You could try the same argument semantics used by the "Gdi32"
function CreateDIBSection which returns an array of bytes as a
pointer argument.
The c# function uses [In][Out] ref IntPtr to represent the array of
bytes returned for the pointer argument passed to CreateDIBSection.
see example:
[DllImport("gdi32.dll")]
static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref
BITMAPINFO pbmi,
uint iUsage, [In][Out] ref IntPtr ppvBits, IntPtr hSection, uint
dwOffset);
"Stephen Cawood" <cawood@xxxxxxxxxx> wrote in message
news:3y7gg.16349$JX1.2431@xxxxxxxxxxx
I posted this question a few days ago, but it hasn't been resolved
so I'm trying again (with better info).
I'm trying to access a C++ .lib from C#. I can get an int back
fine, the problem I'm having is returning an array of binary data.
any ideas?
thanks in advance...
.lib contains this function:
/-Call create() to create a bitmap of (10*scale) x (*10*scale)
bytes
//create() will fill an unsigned char array with 100*scale*scale
bytes
//
//create ID=567, 5 pixels/bit, total image will be 50x50 pixels
//this function will malloc room if image is NULL
//returns -1 if problem, 0 otherwise
int create(int id, int scale, unsigned char *image);
wrapper DLL:
WIN32DLL_API int create_wrapped(int id, int scale, unsigned char
*image)
{
return create(id, scale, image);
}
[DllImport("Wrapper.dll", EntryPoint="create_wrapped")]
public static extern int create_wrapped(int id, int scale, byte[]
image);
byte[] bArray = new byte[500];
create_wrapped(0,5,bArray); //bArray = array of zeros
notes:
I've also tried...
public static extern int create_wrapped(int id, int scale,
[Out][MarshalAs(UnmanagedType.LPArray, SizeConst=500)]byte[]
image); //bArray = array of zeros
public static extern int create_wrapped(int id, int scale,
[MarshalAs(UnmanagedType.LPArray)]byte[] image); //bArray = array
of zeros
public static extern int create_wrapped(int id, int scale,[Out]
IntPtr image); //returns -1 failure
.
- Follow-Ups:
- Re: C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- References:
- C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- From: Michael Phillips, Jr.
- Re: C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- From: Michael Phillips, Jr.
- Re: C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- From: Michael Phillips, Jr.
- Re: C# - getting binary data from .lib
- From: Stephen Cawood
- Re: C# - getting binary data from .lib
- From: Michael Phillips, Jr.
- C# - getting binary data from .lib
- Prev by Date: Re: C# - getting binary data from .lib
- Next by Date: Re: C# - getting binary data from .lib
- Previous by thread: Re: C# - getting binary data from .lib
- Next by thread: Re: C# - getting binary data from .lib
- Index(es):
Relevant Pages
|