Here's the code from the example at Microsoft put together into a single file that will compile with gcc 4.2.something.
A few things to note:
- I've added variables rows and cols - these control the size of the range affected in excel.
- I had to add some GUID definitions to the file since not using MS compiler
- You need to link the ole32 and oleaut32 libraries - .lib for VS, .a for gcc
- nv3 was spot-on saying that you can simply use the buffer for SysAllocString
- I've included the entire source in the interests of completeness
#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <ole2.h> // OLE2 Definitions
const GUID GUID_NULL = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
const GUID IID_IDispatch = {0x00020400, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
int cols=8, rows=16;
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
MessageBox(NULL, L"NULL IDispatch passed to AutoWrap()", L"Error", 0x10010);
_exit(0);
}
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
wchar_t buf[200];
char szName[200];
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
wsprintf(buf, L"IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
MessageBox(NULL, buf, L"AutoWrap()", 0x10010);
_exit(0);
return hr;
}
VARIANT *pArgs = new VARIANT[cArgs+1];
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
wsprintf(buf, L"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
MessageBox(NULL, buf, L"AutoWrap()", 0x10010);
_exit(0);
return hr;
}
va_end(marker);
delete [] pArgs;
return hr;
}
int main()
{
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
if(FAILED(hr)) {
MessageBox(NULL, L"CLSIDFromProgID() failed", L"Error", 0x10010);
return -1;
}
IDispatch *pXlApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);
if(FAILED(hr)) {
MessageBox(NULL, L"Excel not registered properly", L"Error", 0x10010);
return -2;
}
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);
}
IDispatch *pXlBooks;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
pXlBooks = result.pdispVal;
}
IDispatch *pXlBook;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Add", 0);
pXlBook = result.pdispVal;
}
VARIANT arr;
arr.vt = VT_ARRAY | VT_VARIANT;
{
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = rows;
sab[1].lLbound = 1; sab[1].cElements = cols;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
}
for(int i=1; i<=rows; i++)
{
for(int j=1; j<=cols; j++)
{
VARIANT tmp;
tmp.vt = VT_I4;
tmp.lVal = i*j;
long indices[] = {i,j};
SafeArrayPutElement(arr.parray, indices, (void *)&tmp);
}
}
IDispatch *pXlSheet;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);
pXlSheet = result.pdispVal;
}
IDispatch *pXlRange;
{
VARIANT parm;
parm.vt = VT_BSTR;
wchar_t buffer[32];
wsprintf(buffer, L"%c%d:%c%d", 'A'+0, 1, 'A'+cols-1, rows);
parm.bstrVal = SysAllocString(buffer);
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
VariantClear(&parm);
pXlRange = result.pdispVal;
}
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);
MessageBox(NULL, L"All done.", L"Notice", 0x10000);
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L"Saved", 1, x);
}
AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);
pXlRange->Release();
pXlSheet->Release();
pXlBook->Release();
pXlBooks->Release();
pXlApp->Release();
VariantClear(&arr);
CoUninitialize();
return 0;
}