it works! wow, this took some time. anyway, here's the winning combination.
thanks again.
C .lib
-------------------
/-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);
C++ Wrapper
-------------------
WRAPPER_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;
}
C# Accessing the wrapper function
-------------------
// create
[DllImport("Wrapper.dll", EntryPoint="create_wrapped")]
public static extern int create_wrapped(int id, int scale, [In][Out] ref
IntPtr image);
C# Using the data
-------------------
// Allocate unmanaged memory - must be freed with
Marshal.FreeHGlobal(ptrImage)
IntPtr ptrImage = Marshal.AllocHGlobal(2500);
// Try to copy the unmanaged bytes to a managed array
try
{
// Get a pointer to an unmanaged byte array which contains the image
label1.Text = create_wrapped(0, 5, ref ptrImage).ToString(); //return 0 for
success
byte[] bManagedArray = new byte[2500];
// Read through entire pointer byte by byte and put into managed array
for (int i = 0; i < bManagedArray.Length; i++)
{
bManagedArray[i] = Marshal.ReadByte(ptrImage, i);
}
// custom function to Write the PGM image out to a file
writeImageToFile(bManagedArray);
}
catch (ArgumentNullException ex)
{
MessageBox.Show(ex.Message, "Marshal Copy Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
finally
{
// Free the unmanaged memory.
Marshal.FreeHGlobal(ptrImage);
}
[quoted text, click to view] "Stephen Cawood" <cawood@canada.com> wrote in message
news:FK6fg.973$771.888@edtnps89...
> I'm trying to access a C++ .lib from C#.
> I have a working wrapper DLL (I can get back simple things like int), but
> I'm having issues dealing with complex data types.
>
> For example, the .lib contains this function:
>
> int create(int id, int scale, unsigned char *image);
>
> In the wrapper DLL I have this function:
>
> WIN32DLL_API int create_wrapped(int id, int scale, unsigned char *image)
> {
> return create(id, scale, image);
> }
>
> I also tried to return the unsigned char* like this:
>
> WIN32DLL_API int create_wrapped_returnimage(int id, int scale, unsigned
> char *image)
> {
> create(id, scale, image);
> return image;
> }
>
> In C#, I've tried to access the function like this:
>
> [DllImport("Win32DLL.dll",EntryPoint="create_wrapped_returnimage")]
> public static extern IntPtr create_wrapped_returnimage(int artag_id, int
> scale, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder image);
>
> I've tried various data types to try and deal with the "unsigned char
> *image," but I haven't found a solution.
> Can someone suggest the best way to deal with this? Should I be
> converting the unsigned char* to a different type within the C++ wrapper
> function? If so, some sample code would be helpful.
>
> Thanks in advance.
>
>
>