我在Excel插件(xll)中具有特定功能。
该插件是专有的,我们无权访问源代码。但是,我们需要调用插件中包含的某些函数,并且我们想从C#程序中调用它。
目前,我正在考虑编写一个使用xlopers调用Excel函数的C++接口(interface),然后从C#调用此C++接口(interface)。
是否有任何对此类问题有过经验的人知道什么是对此的最佳解决方案?
安东尼
最佳答案
您需要创建一个假xlcall32.dll ,并将其与XLL放在同一目录中(不要在路径中放入excel自己的xlcall32.dll)。这是一些代码:
# 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;}
现在,假设我有一个名为xll-dll.xll的XLL,其中包含一个名为(使用“depends.exe”来查找导出的函数的名称)的函数xlAdd,它会添加两个 double 值:
extern“C” __declspec(dllexport)XLOPER * __cdecl xlAdd(XLOPER * pA,XLOPER * pB);
以下代码调用它:
# 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();}
我的exe实际运行了(令我惊讶),并按预期输出了3。您必须对XLL实际上期望参数有一些了解。如果它分配了一些内存,则必须检查#define xlbitDLLFree 0x4000
在您的XLOPER c->类型上设置,然后回调“xlAutoFree”。