Problem getting correct parameters for C# P/Invoke call to C++ dll
- by Jim Jones
Trying to Interop a functionality from the Outside In API from Oracle.
Have the following function:
SCCERR EXOpenExport {VTHDOC hDoc, VTDWORD dwOutputId, VTDWORD dwSpecType,
VTLPVOID pSpec, VTDWORD dwFlags, VTSYSPARAM dwReserved, VTLPVOID pCallbackFunc,
VTSYSPARAM dwCallbackData, VTLPHEXPORT phExport);
From the header files I reduced the parameters to:
typedef VTSYSPARAM VTHDOC, VTLPHDOC *
typedef DWORD_PTR VTSYSPARAM
typedef unsigned long DWORD_PTR
typedef unsigned long VTDWORD
typedef VTVOID* VTLPVOID
#define VTVOID void
typedef VTHDOC VTHEXPORT, *VTLPEXPORT
These are for 32 bit windows
Going through the header files, the example programs, and the documentation I found:
1. That pSpec could be a pointer to a buffer or NULL, so I set it to a IntPtr.Zero (documentation).
2. That dwFlags and dwReserved according to the documentation "Must be set by the developer to 0".
3. That pCallbackFunc can be set to NULL if I don't want to handle callbacks.
4. That the last two are based on structs that I wrote C# wrappers for using the [StructLayout(LayoutKind.Sequential)]. Then instatiated an instance and generated the parameters by first creating a IntPtr with Marshal.AllocHGlobal(Marshal.SizeOf(instance)), then getting the address value which is passed as a uint for dwCallbackData and a IntPtr for phExport.
The final parameter list is as follows:
1. phDoc as a IntPtr which was loaded with an address by the DAOpenDocument function called
before.
2. dwOutputId as uint set to 1535 which represents FI_JPEGFIF
3. dwSpecType as int set to 2 which represents IOTYPE_ANSIPATH
4. pSpec as an IntPtr.Zero where the output will be written
5. dwFlags as uint set to 0 as directed
6. dwReserved as uint set to 0 as directed
7. pCallbackFunc as IntPtr set to NULL as I will handle results
8. dwCallBackDate as uint the address of a buffer for a struct
9. phExport as IntPtr to another struct buffer
still get an undefined error from the API. Meaning that the call returns a 961 which is not defined in any of the header files. In the past I have gotten this when my choice of parameter types are incorrect.
I started out using Interop Assistant which was helpful in learning how many of the parameter types get translated. It is however limited by how well I am able to glean the correct native type from the header files. For example the hDoc parameter used in the preceding function was defined as a non-filesytem handle, so attempted to use Marshal to create a handle, then used an IntPtr, and finally it turned out to be an int (actually it was &phDoc used here).
So is there a more scientific way of doing this, other than trial and error?
Jim