从C#调用Excel / DLL / XLL功能 [英] Calling Excel/DLL/XLL functions from C#

查看:422
本文介绍了从C#调用Excel / DLL / XLL功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Excel插件(XLL)某一特定功能。
中的插件是专有的,我们没有访问源代码。然而,我们需要调用包含在插件中的一些功能,我们想从C#程序中调用它。



目前,我在想编写C ++接口调用的Excel函数与xlopers,则调用此C ++接口从C#。



有谁谁拥有这样的问题,以往的经验知道什么是最好的解决办法?



安东尼


解决方案

您需要创建一个假xlcall32 .DLL ,把它放在同一目录下XLL(不要把Excel的自己xlcall32.dll在PATH)。下面是一些代码:



 #包括LT&;&WINDOWS.H GT; 

的typedef无效* LPXLOPER;

的externC无效__declspec(dllexport)的XLCallVer(){}

的externCINT __declspec(dllexport)的Excel4(INT xlfn,LPXLOPER operRes,诠释计数, ...){返回0; }

的externCINT __declspec(dllexport)的Excel4v(INT xlfn,LPXLOPER operRes,诠释计数,LPXLOPER远OPERS []){返回0;}






现在假设我有一个名为XLL XLL-dll.xll了一个名为(使用功能依赖.EXE找出的导出函数的名称)xlAdd那么好增加了两个双打:
的externC__declspec(dllexport)的XLOPER * __cdecl xlAdd(XLOPER * pA的,XLOPER * PB);



下面的代码调用它:






 #包括LT&;&WINDOWS.H GT; 
#包括LT&;&iostream的GT;

//你自己的头,它定义XLOP​​ERs
#包括LT&;解析器/ XLL / xloper.hpp>

//函数指针服用2 XLOPERS
的typedef XLOPER *(* __cdecl xl2args)(XLOPER *,* XLOPER);

无效测试(){
///得到XLL地址
HINSTANCE H =调用LoadLibrary(XLL-dll.xll);
如果(H!= NULL){
xl2args MYFUNC;
///让我XLL-dll.xll函数地址
MYFUNC =(xl2args)GetProcAddress函数(H,xlAdd);
如果{//处理错误
FreeLibrary则(H)(MYFUNC!); }
,否则{///建立一些XLOPERS,调用远程函数
XLOPER A,B,* C;
a.xltype = 1; a.val.num = 1;
b.xltype = 1; b.val.num = 2;
C =(* MYFUNC)(安培;一,和b);
的std ::法院LT&;< <XLL的呼唤;< C-> val.num<<的std :: ENDL; }
FreeLibrary则(H); }
}

INT主要()
{测试();}






我的exe实际工作(我自己都感到惊讶),而输出3预期。你必须有一个什么样的实际XLL预计,参数的一些知识。如果分配一些内存,必须检查的#define xlbitDLLFree 0x4000的
设为您XLOPER C->类型,再打xlAutoFree。


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

解决方案

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

这篇关于从C#调用Excel / DLL / XLL功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆