I have an old XLL written in C which I'd like to wrap into a C# class library. I am able to invoke any of these functions which take a "void" argument successfully and marshal the result using:
1) A modified version of the ExcelDnaLoader project from the ExcelDna solution using the XLOper class and its marshalers. (Thanks Govert.)
I cannot however invoke any of the methods that take a "Oper*" arguments without unbalancing the stack.
I tried writing an Oper" struct in C#:
[StructLayout(LayoutKind.Explicit)]
public unsafe struct Oper
{
[StructLayout(LayoutKind.Explicit)]
unsafe public struct OperArray // In OPER
{
[FieldOffset(0)]
public Oper* pOpers;
[FieldOffset(4)]
public ushort Rows;
[FieldOffset(6)]
public ushort Columns;
}
[FieldOffset(0)]
public double numValue; // In OPER
[FieldOffset(0)]
public XlString* pstrValue; // In OPER
[FieldOffset(0)]
public ushort boolValue; // In OPER
[FieldOffset(0)]
public ushort /*ExcelError*/ errValue; // In OPER
[FieldOffset(8)]
public XlType xlType; // In OPER
}
Whereas in C the Oper struct is defined as:
typedef struct _oper
{
union
{
double num; /* xltypeNum */
LPSTR str; /* xltypeStr */
WORD boolean; /* xltypeBool */
WORD err; /* xltypeErr */
struct
{
struct _oper *lparray;
WORD rows;
WORD columns;
} array; /* xltypeMulti */
} val;
WORD type;
} OPER, *LPOPER ;
I tried passing an argument to:
unsafe delegate IntPtr UdfDelegate(Oper* a1);
which points to the C function:
XLFUNC(LPXLOPER) CDS_Test2(Oper* a1)
However this crashes with a complaint that the stack is unbalanced because the signatures don't match. Does anyone have any idea of how to do this properly?