Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Monday, November 12, 2007 1:50:57 PM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


Hello,

I have a rather wierd problem. I have a VC++ 6 dll that exposes a function that combines images. The function utilizes the LMemoryFile::GetInfo function while loading an image from the hard drive into memory. I created a quick C++ console app to test the implementation and everything works beautifully.

I then created a C# app and used the DllImport feature to call the function to start the work. The function is being called, and the parameters are being passed (I added code to write the parameters to a text file to verify). However, I'm not able to successfully call the GetInfo method on the LMemoryFile object.

This is the sequence of events that my code goes through (I tried pasting the code but it lookes horrible):


Verify that the file being referenced exists
If so, create a FILEINFO, LBuffer, LBitmap and LMemoryFile object
Call SetHandle on the LBuffer object passing in the HGLOBAL object used to verify file
If that succeeds, call the GetInfo method on the LMemoryFile object passing in the LBuffer and FILEINFO object (this is where it fails).


It then continues processing the file.
As I stated, the process works beautifully as long as I don't call it from C#. Am I missing something in the configuration that I should change? I've never had this much trouble with a P/Invoke.

Thanks for any help you can give.


 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

#2 Posted : Tuesday, November 13, 2007 5:07:40 AM(UTC)

Adnan Ismail  
Guest

Groups: Guests
Posts: 3,022

Was thanked: 2 time(s) in 2 post(s)

Can you tell which version of LEADTOOLS toolkit you are using? Also, can you isolate your problem in a small working project (not your full application) that I can check for you? If you want to send the project, please put it in a ZIP or RAR file.
 
#3 Posted : Tuesday, November 13, 2007 5:58:09 AM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


I'm using Version 11.5 (I inherited this project...it was originally written in 2001). I've attached the Project that contains the error. There's other projects that you'll probably need, but I'm trying to keep the attachments small :).

The method that is giving me troubles starts at line 193 in cfxImage.cpp. It runs fine down to line 257. I added some WriteError's in to peek into the variables and added the results into the code file.
File Attachment(s):
CfxImage.rar (29kb) downloaded 31 time(s).
 
#4 Posted : Tuesday, November 13, 2007 3:42:00 PM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


Hello,

I just wanted to follow up with some information that I found that helped me get further into this (in case someone else runs into it).

When calling the C++ 6 dll I was using DllImport. The C++ dll was expecting char * and BSTR type parameters. I added the MarshalAs attributes for each one, however it still did not help.

The solution to get me further into the process was to change the way that I encoded the string into the byte[]. I used the standard ASCIIEncoding.UTF32.GetBytes(). When using this encodign method, only the first character of the string was being passed to the dll. The fix so far seems to be using the Encoding.ASCII.GetBytes(). I still have a few errors, but I have a feeling it may be the way that C# is marshaling the object for the BSTR parameters. I haven't started working on that yet, but I'll update when I know more.
 
#5 Posted : Wednesday, November 14, 2007 6:00:48 AM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


Here's where I'm at now. The proper parameters are being passed into the dll and everything works fine until it gets to this code block:

FILEINFO info;
LBuffer lbuf;
m_pWorkingImage = new LBitmap;
LMemoryFile lmem( m_pWorkingImage );

m_LastResult = lbuf.SetHandle( &hGlobal );

if(m_LastResult==SUCCESS)
{
m_LastResult = lmem.GetInfo(lbuf, &info,0,NULL);
}

The GetInfo method is the one that's causing the problem now. As I stated previously, I only get this when I attempt to call the generate method through a C# DllImport call. Running this from a C++ console app works beautifully.

Any guidance would be greatly appreciated.
 
#6 Posted : Wednesday, November 14, 2007 6:16:13 AM(UTC)

Adnan Ismail  
Guest

Groups: Guests
Posts: 3,022

Was thanked: 2 time(s) in 2 post(s)


Since our toolkit is working properly when called from
within a C/C++ program, you're probably right that the problem is related to data marshalling.


Is the numerical value of hGlobal in the C# side of the code identical to its value in the unmanaged C++ side?

 
#7 Posted : Wednesday, November 14, 2007 6:28:47 AM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


The hGlobal is not used within the C# side. The way the code is set up, I have the CfxImage dll that does most of the work. There's a CfxEngine dll that creates parses a string input and ensures that the data is valid. The CfxImage dll only receives a string of file names that contain the image name, region information and other settings. The CfxImage dll then parses the text files and passes the necessary information in to the Generate method (where the GetInfo problem is).

There's also another dll (CfxEngineExt.dll) that wraps the CfxEngine.dll functions and exposes them. The C# application calls the CfxEngineExt.dll and passes in byte arrays for the char * parameters.

I've been going through the help files and everything looks good (and the fact that it runs when called by a C++ app proves it works). My thoughts are leaning towards the possibility of the C# app restricting file access. I've never heard of something like that happening, but I'm searching the net now to see if I can find some information.
 
#8 Posted : Wednesday, November 14, 2007 6:57:20 AM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


As a test, I created and exposed another method. This one is exactly the same as the first except I hard coded the parameters inside the C++ dll to verify if it's a marshalling issue.

I got the same results as before. It works fine from within a c++ app, but the dll won't load the image when called through a C# app.
 
#9 Posted : Wednesday, November 14, 2007 3:55:56 PM(UTC)

lclay  
lclay

Groups: Registered
Posts: 8


Mystery Solved!

There wasn't a problem with the way C# was calling the dll. While I was working through the code this afternoon, I got a BSOD. A mem test caused my machine to reboot in the middle (no error reported...but I think it's safe to say there's some bad memory).

I copied the dll's and C# app over to another machine and it ran with no problem. Thanks for the help and suggestions.
 
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2024, Yet Another Forum.NET
This page was generated in 0.183 seconds.