Unmanaged From C#
Posted on 2003-11-20
Still trying my OCR Program....
This Function from this .dll Library (for an OCR Project) does an OCR Job and then has a function I can call called "GetJobResults" which takes the JobNumber, an Integer (How many bytes to allocate for the Results) and a "results" Structure. The code looks as follows...
--------C++ Code---------------(Original Format)---------------
typedef struct tagTOCRRESULTSHEADER
typedef struct tagTOCRRESULTSITEM
unsigned short StructId;
unsigned short OCRCha;
unsigned short XPos;
unsigned short YPos;
unsigned short XDim;
unsigned short YDim;
typedef struct tagTOCRRESULTS
EXTERN_C long WINAPI TOCRGetJobResults(long JobNo, long *ResultsInf, TOCRRESULTS *Results);
I cannot get this to properly export to a DLL.( There are a lot of other functions too, this is the one I am ..'presently' stuck on ..)
I am rewriting this into C#. However since C# does not allow pointers (and even the 'unsafe' blocks don't allow them very well either) it isn't wanting to work. I'm fully aware of the 'Ref' keyword, and it has proved utterly useless to me. The Function works as follows.
When a Job is Performed (using a different function that returns the JobNumber as an Integer), and then this TOCRGetJobResults function is invoked, the JobNo is passed through it. The ResultsInf is set to a number of bytes if, and ONLY if the third parameter is set to 0. If the parameter is 0, then ResultsInf is set to an Integer of the number of bytes needed to store the results of the OCR Process. This function then must be invoked a second time, passing the same JobNo, ResultsInf, but a TOCRResults OBJECT/Structure which THEN put the TOCRResults Object/structure into the memory area that is large enough to contain the results, and puts the results in Respectively.
The TOCRResults Structure calls upon two other object structures.
TOCRResultsHeader and TOCRResultsItem. TOCRResultsItem contains the actual Array of Character with the OCR results, and TOCRResultsHeader contains the number of Items in the array with some other data. All of this is performed in a Commercial .lib file that I cannot edit (trust me, I would if I could).
Because of the way the pointers are structured to so closely work with memory addresses, I just can't make C# talk to this library right. I have debugged MOST of this program, and this is pretty much the last step (getting the OCR Results after I've already done the OCR Job!!)
I have tried making the structures classes and structures in C#, neither changes very much except I encounter more problems with certain other aspects of the program, so I'm just going to find one that works and work around it.
here is my 'CURRENT' C# code. Please note, this Compiles and runs, but it does not work.
I will send the Entire .zip Solution to anyone who is willing to aid me and needs to see it.
public struct TOCRResultsHeader
public int StructId;
public int XPixelsPerInch;
public int YPixelsPerInch;
public int NumItems;
public float MeanConfidence;
public struct TOCRResultsItem
public int StructId;
public int OCRCha;
public float Confidence;
public ushort XPos;
public ushort YPos;
public ushort XDim;
public ushort YDim;
public struct TOCRResults
public TOCRResultsHeader Hdr;
public TOCRResultsItem Item;
public struct API
public static extern int TOCRGetJobResults(int JobNo, ref int ResultsInf,ref TOCRResults Results);
In the main body of the C++ File, the TOCRResults Object is declared as follows.
TOCRRESULTS *TOCRResults = 0;
of course, this is impossible in C#, as pointing to a managed Structure isn't allowed in the language. So I must define TOCRResults as such...
TOCRResults TOCRResults = new TOCRResults();
Which is the proper way to initialize an object. However it is obvious this object is somehow meant to be set to 0 through use of a pointer, and I just can't do that in C#, even if I use "unsafe" blocks, it doesn't work.
I'm becomming very desperate here. It seems to me that C# is just incapable of what I am wanting to do, however I need to use it for this, I don't want a bunch of .dll's floating about in my program, especially unmanaged ones that are just hopping in and out of managed source code, it will make debugging in the future a massive chore.
If anyone can help me, I would REALLY appreciate it.
Further Information :
Once GetJobResults is called for the first time, ResultsInf is used to Instantiate TOCRResults Object with enough memory to hold the Data. Since C# utilizes the garbage collector, this is un-needed, but the .lib commercial library still requires I do something with this. Again, I'll send the solution to anyone who will help. This is ..becoming very frustrating.