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

发布于 2024-08-15 13:31:52 字数 205 浏览 7 评论 0原文

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

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

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

安东尼

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

勿挽旧人 2024-08-22 13:31:52

您需要创建一个假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”。

You need to create a fake xlcall32.dll, put it in the same directory as your XLL (do not put excel's own xlcall32.dll in the PATH). Here is some code:

# 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".

眼藏柔 2024-08-22 13:31:52

您可能想尝试 XLL Plus http://www.planatechsolutions.com/xllplus/default.htm 。价格有点贵,但是
XLL 包装库功能正是您所寻找的:

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

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"

摇划花蜜的午后 2024-08-22 13:31:52

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

An Excell add-in DLL might be written in C#. If so, then you can probably bypass Excel altogether. Might need a wrapper though.

贪了杯 2024-08-22 13:31:52

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

check whether assembly is available in program files where you install the plguin,
reference that assembly directly to your c# project - check the object browser for your class, method or object

雪花飘飘的天空 2024-08-22 13:31:52

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

You should be able to use reflection to get access to your addin. try using The Reflector to see what's available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文