从C#调用Excel/DLL/XLL函数

Blu*_*rin 7 c# c++ excel xll

我在Excel插件(xll)中有一个特定的功能.插件是专有的,我们无权访问源代码.但是我们需要调用addin中包含的一些函数,我们想从C#程序中调用它.

目前,我正在考虑编写一个C++接口,用xlopers调用Excel函数,然后从C#调用这个C++接口.

有过此类问题之前经验的人是否知道什么是最佳解决方案?

安东尼

red*_*der 4

您需要创建一个假的 xlcall32.dll,将其放在与 XLL 相同的目录中(不要将 excel 自己的 xlcall32.dll 放在 PATH 中)。这是一些代码:

# 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;}
Run Code Online (Sandbox Code Playgroud)

现在假设我有一个名为 xll-dll.xll 的 XLL,其函数名为(使用“depends.exe”查找导出函数的名称)xlAdd,它可以添加两个双精度数: 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();}
Run Code Online (Sandbox Code Playgroud)

我的 exe 实际上可以工作(令我自己惊讶),并按预期输出 3。您必须了解 XLL 实际期望的参数。如果它分配了一些内存,则必须检查 XLOPER c->type 上是否设置了#define xlbitDLLFree 0x4000,并回调“xlAutoFree”。