Discussion:
Problem using unmanaged code in /clr application
(too old to reply)
tomdickens
2010-02-22 00:46:01 UTC
Permalink
I have a Windows Forms application, Visual C++ 2005, compiling it using /clr.
I need to use the image-handling library CImg, which is packaged simply as a
header file CImg.h that you include in your project.

I added CImg.h to stdafx.h, inside #pragma unmanaged/managed preprocessor
instructions. The code compiles just fine.

However, when I construct a CImg object and then try to write text into it
to display, I get a memory error -
System.AccessViolationException: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
at cimg_library.CImg<unsigned char>.draw_text<unsigned char>(CImg<unsigned
char>* , Int32 , Int32 , SByte* , Byte* , Int32 , Single , UInt32 )

Is this because of using unmanaged memory in a managed code? I thought IJW
would handle this. I've asked this same question on the CImg forum but have
no reszponse yet.


Thanks,
Tom

Here is the detailed code:

Put in stdafx.h:
#pragma once
#pragma unmanaged
#pragma comment (lib, "shell32.lib")
#pragma comment (lib, "gdi32.lib")
#pragma comment (lib, "user32.lib")
#define cimg_OS 2
#define cimg_display_type 2
#include "CImg.h"
using namespace cimg_library;
#pragma managed

Call the functions:
CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8
bits per color component.
img.fill(0); // Set pixel values to 0 (color : black)
unsigned char purple[] = { 255,0,255 }; // Define a purple color
img.draw_text(100,100,"Hello World",purple); // IT DIES HERE ---- Draw a
purple "Hello world" at coordinates (100,100).
img.display("My first CImg code"); // Display the image in a display window.
David Lowndes
2010-02-22 11:01:06 UTC
Permalink
Post by tomdickens
Is this because of using unmanaged memory in a managed code?
Tom,

I'm not familiar with CImg, but what happens if you use the same
source code in a native application?

Dave
tomdickens
2010-02-24 03:32:01 UTC
Permalink
The same code works fine in an MFC application.

CImg is packaged as a very large header file, CImg.h. It's a C++
Template-based image-handling class that a lot of people seem to use. (I
posted this question on their forum but haven't gotten a reply.)

I could post the CImg.h parts that are required here, but I don't know if
that would be productive. Probably the most important part is that the image
memory is allocated using 'new.' Since this worked in MFC, I'm really
thinking that the managed/unmanaged interop is not working here.

I'm fairly new to trying to use managed and unmanaged code together, it has
given me loads of trouble!

Thanks,
Tom
Post by David Lowndes
Post by tomdickens
Is this because of using unmanaged memory in a managed code?
Tom,
I'm not familiar with CImg, but what happens if you use the same
source code in a native application?
Dave
.
David Lowndes
2010-02-24 09:47:37 UTC
Permalink
Post by tomdickens
The same code works fine in an MFC application.
OK. Is the code absolutely correct though? i.e. is the native version
working partly by chance/circumstance?
Post by tomdickens
I could post the CImg.h parts that are required here, but I don't know if
that would be productive.
Unlikely.
Post by tomdickens
Probably the most important part is that the image
memory is allocated using 'new.' Since this worked in MFC, I'm really
thinking that the managed/unmanaged interop is not working here.
Can you show just the relevant part of the code (if you think it would
make sense to someone not familiar with using CImg)?

Dave
tomdickens
2010-02-27 02:54:01 UTC
Permalink
David,

The code fails when stripped to:

CImg<unsigned char> img(640,400,1,3);
img.fill(0);
img.display();

at the img.display() call.


From CImg.h, I believe the relevant part of the constructor code is:

explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned
int dz=1, const unsigned int dv=1):
is_shared(false) {
const unsigned long siz = dx*dy*dz*dv;
if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new
T[siz]; }
else { width = height = depth = dim = 0; data = 0; }
}

Then the call to display() is:
//! Display an image in a window with a title \p title, and wait a
'is_closed' or 'keyboard' event.\n
const CImg<T>& display(const char *const title=0, const bool
display_info=true) const {
CImgDisplay disp;
return _display(disp,title,display_info);
}

The CImgDisplay constructor is:
//! Create an empty display window.
CImgDisplay():
width(0),height(0),normalization(0),title(0),
window_x(0),window_y(0),window_width(0),window_height(0),

mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),

is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
min(0),max(0) {}

CImgDisplay is a struct containing all these variables that define a display.

I'm not very experienced using interop between managed (/clr) and unmanaged
code, such as in CImg.h. Could the use of "new" by CImg to allocate memory be
the culprit??

I'm certainly not sure that this is enough detail to help you see what the
problem might be.

Thanks a lot,
Tom
Post by David Lowndes
Post by tomdickens
The same code works fine in an MFC application.
OK. Is the code absolutely correct though? i.e. is the native version
working partly by chance/circumstance?
Post by tomdickens
I could post the CImg.h parts that are required here, but I don't know if
that would be productive.
Unlikely.
Post by tomdickens
Probably the most important part is that the image
memory is allocated using 'new.' Since this worked in MFC, I'm really
thinking that the managed/unmanaged interop is not working here.
Can you show just the relevant part of the code (if you think it would
make sense to someone not familiar with using CImg)?
Dave
.
David Lowndes
2010-02-27 10:21:09 UTC
Permalink
Post by tomdickens
CImg<unsigned char> img(640,400,1,3);
img.fill(0);
img.display();
at the img.display() call.
Tom,

Is the call to display failing, or somewhere deeper inside the guts of
display?
I'd assume it's deeper inside (what you showed looks straightforward
enough), and if so where precisely? If it's a template library you
should have the source.

Dave

David Wilkinson
2010-02-22 13:57:25 UTC
Permalink
Post by tomdickens
I have a Windows Forms application, Visual C++ 2005, compiling it using /clr.
I need to use the image-handling library CImg, which is packaged simply as a
header file CImg.h that you include in your project.
I added CImg.h to stdafx.h, inside #pragma unmanaged/managed preprocessor
instructions. The code compiles just fine.
However, when I construct a CImg object and then try to write text into it
to display, I get a memory error -
System.AccessViolationException: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
at cimg_library.CImg<unsigned char>.draw_text<unsigned char>(CImg<unsigned
char>* , Int32 , Int32 , SByte* , Byte* , Int32 , Single , UInt32 )
Is this because of using unmanaged memory in a managed code? I thought IJW
would handle this. I've asked this same question on the CImg forum but have
no reszponse yet.
Thanks,
Tom
#pragma once
#pragma unmanaged
#pragma comment (lib, "shell32.lib")
#pragma comment (lib, "gdi32.lib")
#pragma comment (lib, "user32.lib")
#define cimg_OS 2
#define cimg_display_type 2
#include "CImg.h"
using namespace cimg_library;
#pragma managed
CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8
bits per color component.
img.fill(0); // Set pixel values to 0 (color : black)
unsigned char purple[] = { 255,0,255 }; // Define a purple color
img.draw_text(100,100,"Hello World",purple); // IT DIES HERE ---- Draw a
purple "Hello world" at coordinates (100,100).
img.display("My first CImg code"); // Display the image in a display window.
What is the precise C++ declaration of the method, and how are you calling it?
--
David Wilkinson
Visual C++ MVP
tomdickens
2010-02-26 04:02:01 UTC
Permalink
David,

The code fails when stripped to:

CImg<unsigned char> img(640,400,1,3);
img.fill(0);
img.display();

at the img.display() call.


From CImg.h, I believe the relevant part of the constructor code is:

explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned
int dz=1, const unsigned int dv=1):
is_shared(false) {
const unsigned long siz = dx*dy*dz*dv;
if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new
T[siz]; }
else { width = height = depth = dim = 0; data = 0; }
}

Then the call to display() is:
//! Display an image in a window with a title \p title, and wait a
'is_closed' or 'keyboard' event.\n
const CImg<T>& display(const char *const title=0, const bool
display_info=true) const {
CImgDisplay disp;
return _display(disp,title,display_info);
}

The CImgDisplay constructor is:
//! Create an empty display window.
CImgDisplay():
width(0),height(0),normalization(0),title(0),
window_x(0),window_y(0),window_width(0),window_height(0),

mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),

is_closed(true),is_resized(false),is_moved(false),is_event(false),is_fullscreen(false),
min(0),max(0) {}

CImgDisplay is a struct containing all these variables that define a display.

I'm not very experienced using interop between managed (/clr) and unmanaged
code, such as in CImg.h. Could the use of "new" by CImg to allocate memory be
the culprit??

I'm certainly not sure that this is enough detail to help you see what the
problem might be.

Thanks a lot,
Tom
Post by David Wilkinson
Post by tomdickens
I have a Windows Forms application, Visual C++ 2005, compiling it using /clr.
I need to use the image-handling library CImg, which is packaged simply as a
header file CImg.h that you include in your project.
I added CImg.h to stdafx.h, inside #pragma unmanaged/managed preprocessor
instructions. The code compiles just fine.
However, when I construct a CImg object and then try to write text into it
to display, I get a memory error -
System.AccessViolationException: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
at cimg_library.CImg<unsigned char>.draw_text<unsigned char>(CImg<unsigned
char>* , Int32 , Int32 , SByte* , Byte* , Int32 , Single , UInt32 )
Is this because of using unmanaged memory in a managed code? I thought IJW
would handle this. I've asked this same question on the CImg forum but have
no reszponse yet.
Thanks,
Tom
#pragma once
#pragma unmanaged
#pragma comment (lib, "shell32.lib")
#pragma comment (lib, "gdi32.lib")
#pragma comment (lib, "user32.lib")
#define cimg_OS 2
#define cimg_display_type 2
#include "CImg.h"
using namespace cimg_library;
#pragma managed
CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8
bits per color component.
img.fill(0); // Set pixel values to 0 (color : black)
unsigned char purple[] = { 255,0,255 }; // Define a purple color
img.draw_text(100,100,"Hello World",purple); // IT DIES HERE ---- Draw a
purple "Hello world" at coordinates (100,100).
img.display("My first CImg code"); // Display the image in a display window.
What is the precise C++ declaration of the method, and how are you calling it?
--
David Wilkinson
Visual C++ MVP
.
Continue reading on narkive:
Loading...