Domanda

ho una particolare funzione in un componente aggiuntivo di Excel (XLL). Il componente aggiuntivo è proprietario e non abbiamo accesso al codice sorgente. Tuttavia abbiamo bisogno di chiamare alcune funzioni contenute all'interno del componente aggiuntivo e vorremmo chiamarlo da un programma C #.

Al momento, stavo pensando di scrivere un C ++ un'interfaccia chiamando la funzione di Excel con xlopers, quindi chiamare il C ++ interfaccia da C #.

C'è qualcuno che ha precedenti esperienze di questo tipo di problemi sa cosa sarebbe la soluzione migliore per questo?

Anthony

È stato utile?

Soluzione

È necessario creare un xlcall32.dll falso , metterlo nella stessa directory del XLL (non mettere proprio xlcall32.dll di eccellere nel PATH). Ecco il codice:

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

Ora supponiamo che ho un XLL chiamato XLL-dll.xll con una funzione chiamata (uso "Depends.exe" per scoprire i nomi delle funzioni esportate) xlAdd che ben aggiunge due doppie: extern __declspec "C" (dllexport) XLOPER * __cdecl xlAdd (XLOPER * pA, XLOPER * PB);

Il codice seguente chiama:


# 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();}

Il mio exe effettivamente funziona (con mia grande sorpresa), e l'uscita 3 come previsto. È necessario avere una certa conoscenza di ciò che il XLL si aspetta in realtà per i parametri. Se si alloca po 'di memoria, è necessario verificare se il 0x4000 #define xlbitDLLFree è impostato sul vostro XLOPER c-> tipo, e richiamare "xlAutoFree".

Altri suggerimenti

Si potrebbe provare XLL Inoltre http://www.planatechsolutions.com/xllplus/ default.htm . E 'un po' costoso, ma il  funzione XLL Wrapper biblioteche è esattamente quello che stai cercando:

"A volte è utile essere in grado di chiamare le funzioni add-in di Excel da altri ambienti, come i programmi della riga di comando o applicazioni interattive, scritto in C ++, Java, C # o Visual Basic. Il toolkit Xll Wrapper contiene strumenti , una libreria di runtime, esempi e documentazione per aiutare con lo sviluppo di moduli COM e assembly .NET che avvolgono Excel XLL componenti aggiuntivi "

Un add-in Excel DLL potrebbe essere scritto in C #. Se è così, allora probabilmente si può escludere del tutto Excel. Potrebbe aver bisogno di un involucro però.

verificare se il montaggio è disponibile in file di programma in cui si installa il plguin, di riferimento che il montaggio direttamente sul tuo progetto C # - controllare il browser degli oggetti per la classe, metodo o oggetto

Si dovrebbe essere in grado di utilizzare la riflessione per ottenere l'accesso al tuo componente aggiuntivo. provare a utilizzare il riflettore per vedere cosa c'è a disposizione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top