I have a particular function in an Excel addin(xll). The addin is proprietary and we do not have access to the source code. However we need to call some functions contained within the addin and we would like to call it from a C# program.
Currently, I was thinking of writing a C++ interface calling the Excel function with xlopers, then calling this C++ interface from C#.
Does anybody who has prior experience of this kind of issues know what would be the best solution for that ?
Anthony
XLL files can be opened with Microsoft Excel. If double-clicking an XLL file doesn't open it in Excel, you can do it manually via the File > Options menu. Select the Add-ins category and then choose Excel Add-ins in the Manage drop-down box. Choose the Go button and then Browse to locate it.
Excel allows XLLs to call the C API only when Excel has passed control to the XLL. A worksheet function that is called by Excel can call back into Excel by using the C API.
Meet The VBA EditorExcel has a built-in tool for writing macros called the Visual Basic Editor—or VBA Editor for short. To open that, open a spreadsheet and use the shortcut Alt + F11 (for Mac: Fn + Shift + F11 ). The new window that pops up is called the VBA Editor.
# include <windows.h>
typedef void* LPXLOPER;
extern "C" void __declspec(dllexport) XLCallVer ( ) {}
extern "C" int __declspec(dllexport) Excel4 (int xlfn, LPXLOPER operRes, int count,... ) { return 0; }
extern "C" int __declspec(dllexport) Excel4v(int xlfn, LPXLOPER operRes, int count, LPXLOPER far opers[]) {return 0;}
Now suppose I have an XLL called xll-dll.xll with a function called (use "depends.exe" to find out the names of the exported functions) xlAdd that well adds two doubles: extern "C" __declspec(dllexport) XLOPER * __cdecl xlAdd(XLOPER* pA, XLOPER* pB);
The following code calls it:
# include <windows.h>
# include <iostream>
// your own header that defines XLOPERs
# include <parser/xll/xloper.hpp>
// pointer to function taking 2 XLOPERS
typedef XLOPER * (__cdecl *xl2args) (XLOPER* , XLOPER* ) ;
void test(){
/// get the XLL address
HINSTANCE h = LoadLibrary("xll-dll.xll");
if (h != NULL){
xl2args myfunc;
/// get my xll-dll.xll function address
myfunc = (xl2args) GetProcAddress(h, "xlAdd");
if (!myfunc) { // handle the error
FreeLibrary(h); }
else { /// build some XLOPERS, call the remote function
XLOPER a,b, *c;
a.xltype = 1; a.val.num = 1. ;
b.xltype = 1; b.val.num = 2. ;
c = (*myfunc)(&a,&b);
std::cout << " call of xll " << c->val.num << std::endl; }
FreeLibrary(h); }
}
int main()
{test();}
My exe actually works (to my own surprise), and output 3 as expected. You must have some knowledge of what your XLL actually expects for parameters. If it allocates some memory, you must check if the #define xlbitDLLFree 0x4000 is set on your XLOPER c->type, and call back "xlAutoFree".
You might like to try XLL Plus http://www.planatechsolutions.com/xllplus/default.htm. It's a bit pricey, but the XLL Wrapper Libraries feature is exactly what you are looking for:
"Sometimes it is useful to be able to call your Excel add-in functions from other environments, such as command-line programs or interactive applications, written in C++, Java, C# or Visual Basic. The Xll Wrapper toolkit contains tools, a runtime library, samples and documentation to help with the development of COM modules and .NET assemblies that wrap Excel XLL add-ins"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With