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

7

我有一个特定的功能在Excel插件(xll)中。该插件是专有的,我们没有访问源代码的权限。然而,我们需要调用一些包含在插件中的函数,并希望从C#程序中调用它。

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

有没有之前遇到过这种问题并且有最佳解决方案的人?

安东尼


这可能是一个愚蠢的问题,但你是否尝试过将xll作为普通dll使用呢?(xll只是带有Excel额外接口的dll。)还是问题在于您想要调用的函数需要由Excel在*调用时提供的参数,并且您无法使该调用正常工作? - jtolle
目前,我已经基本按照您所说的做了。我使用xlopers作为参数调用XLL作为DLL(我需要的函数以XLOPERs作为参数),在C++中实现。然后,我编写了一个C#层,将Object[,]转换为xlopers并调用C++函数。我只是想知道是否有更简单的解决方案。 - BlueTrin
5个回答

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;}

现在假设我有一个名为xll-dll.xll的XLL,其中有一个名为xlAdd的函数(使用“depends.exe”查找导出函数的名称),它可以将两个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所需的参数有一定的了解。如果它分配了某些内存,您必须检查XLOPER c->type上是否设置了#define xlbitDLLFree 0x4000,并回调“xlAutoFree”。


3
您也许想尝试XLL Plus http://www.planatechsolutions.com/xllplus/default.htm。虽然价格有些高昂,但是XLL包装库功能正是您所需的:
“有时候,如果能够从其他环境(如C ++、Java、C#或Visual Basic编写的命令行程序或交互式应用程序)调用Excel加载项函数将非常有用。 Xll Wrapper工具包包含工具、运行时库、示例和文档,可帮助开发COM模块和.NET程序集,以包装Excel XLL加载项。”

-1

Excell插件DLL可以用C#编写。如果是这样,那么您可能可以完全绕过Excel。不过可能需要一个包装器。


在这种情况下,我得到的插件是原样的。 它不是由我们开发的,我们没有访问源代码,但是我们想在其他语言中使用XLL中包含的一些函数。 我将编辑我的帖子以提到这个事实。 - BlueTrin

-1

检查安装插件的程序文件中是否可用汇编,直接将该汇编引用到您的C#项目中-在对象浏览器中检查您的类、方法或对象


-4

你应该能够使用反射来访问你的插件。尝试使用Reflector查看可用内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接