【问题标题】:Calling Excel/DLL/XLL functions from C#从 C# 调用 Excel/DLL/XLL 函数
【发布时间】:2009-12-21 15:28:54
【问题描述】:

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

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

有过此类问题经验的人知道什么是最好的解决方案吗?

安东尼

【问题讨论】:

  • 这可能是一个愚蠢的问题,但是您是否尝试过仅将 xll 用作普通 dll ? (xll 只是一个带有 Excel 额外接口的 dll。)或者问题是,您要调用的函数采用当 it 调用时应由 Excel 提供的参数,而您'拨打电话时遇到问题?
  • 目前,我或多或少按照你说的做了。我在 C++ 中使用 xlopers 作为参数(我需要的函数将 XLOPER 作为参数)将 XLL 称为 DLL。然后我编写了一个 C# 层,将 Object[,] 转换为 xlopers 并调用 C++ 函数。我只是想知道是否有人有更简单的解决方案。

标签: c# c++ excel xll


【解决方案1】:

你需要创建一个fake 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,其中有一个名为(使用“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();}

我的 exe 确实有效(令我惊讶的是),并按预期输出 3。您必须对 XLL 对参数的实际期望有所了解。如果它分配了一些内存,你必须检查#define xlbitDLLFree 0x4000 在您的 XLOPER c->type 上设置,然后回调“xlAutoFree”。

【讨论】:

    【解决方案2】:

    您可能想试试 XLL Plus http://www.planatechsolutions.com/xllplus/default.htm。有点贵,但是 XLL Wrapper Libraries 功能正是您正在寻找的:

    “有时,能够从其他环境(例如命令行程序或交互式应用程序,用 C++、Java、C# 或 Visual Basic 编写)调用 Excel 加载项函数很有用。Xll Wrapper 工具包包含工具、运行时库、示例和文档,以帮助开发包装 Excel XLL 加载项的 COM 模块和 .NET 程序集"

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 在这种情况下,我按原样获取插件。它不是由我们开发的,我们不访问源代码,但是我们想使用其他语言中包含在 XLL 中的一些功能。我将编辑我的帖子以提及这一事实。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您应该能够使用反射来访问您的插件。尝试使用The Reflector 看看有什么可用的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多