The link is
http://www.codeguru.com/Cpp/COM-Tech/atl/atl/article.php/c57/Here is the code to 'convert' a TLB into a C# interface declaration which can be read in by EA:
// Tlb2Cs.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void WriteLine (HANDLE fh, LPCTSTR szLine)
{
size_t nLen = _tcslen (szLine);
DWORD dwBytesWritten;
::WriteFile (fh, szLine, (DWORD) nLen, &dwBytesWritten, NULL);
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL);
HANDLE fh = INVALID_HANDLE_VALUE;
TCHAR szLine[2000];
try
{
if (argc != 4)
{
_tprintf (_T("Usage: Tlb2Cs <Typelib> <Namespace> <Outputfile>\n"));
return 1;
}
// read in typelib
Typelib::ILib2MePtr spLib (__uuidof (Typelib::Lib2Me));
spLib->Load (argv[1]);
// create outputfile
fh = ::CreateFile(argv[3], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
_tprintf (_T("Can't create output file\n"));
return 1;
}
// namespace
_stprintf (szLine, _T("namespace %s\n{\n"), argv[2]);
WriteLine (fh, szLine);
//
int nClass = 0;
while (true)
{
Typelib::ILClassPtr spClass = spLib->GetClass (nClass++);
if (spClass == NULL)
break;
switch (spClass->Kind)
{
case TKIND_ENUM:
_stprintf (szLine, _T(" enum %s\n {\n"), (LPCTSTR) spClass->Name);
WriteLine (fh, szLine);
for (int t1=0; t1<spClass->CountVariable; t1++)
{
Typelib::ILVariablePtr spVar = spClass->GetVariable (t1);
_stprintf (szLine, _T(" %s,\n"), (LPCTSTR) spVar->Name);
WriteLine (fh, szLine);
}
_stprintf (szLine, _T(" }\n\n"));
WriteLine (fh, szLine);
break;
case TKIND_DISPATCH:
_stprintf (szLine, _T(" public interface %s\n {\n"), (LPCTSTR) spClass->Name);
WriteLine (fh, szLine);
// attributes
for (int t2 = 0; t2 < spClass->CountVariable; t2++)
{
Typelib::ILVariablePtr spVar = spClass->GetVariable(t2);
_stprintf (szLine, _T("%s %s\n"), (LPCTSTR) spVar->Type, (LPCTSTR) spVar->Name);
WriteLine (fh, szLine);
}
// methods
for (int t3=7; t3<spClass->CountFunction; t3++)
{
Typelib::ILFunctionPtr spFunction = spClass->GetFunction (t3);
switch (spFunction->InvokeKind)
{
// Function
case 1:
{
_stprintf (szLine, _T(" %s %s ("), (LPCTSTR) spFunction->GetReturnType(), (LPCTSTR) spFunction->GetName());
int nParCount = spFunction->ParameterCount;
for (int t4=0; t4<nParCount; t4++)
{
Typelib::ILParameterPtr spPar = spFunction->GetParameter (t4);
TCHAR szParameter[400];
_stprintf (szParameter, _T("%s %s"), (LPCTSTR) spPar->Type, (LPCTSTR) spPar->Name);
_tcscat (szLine, szParameter);
if (t4 < nParCount-1)
_tcscat (szLine, _T(", "));
}
_tcscat (szLine, _T(");\n"));
WriteLine (fh, szLine);
}
break;
// getter
case 2:
{
_stprintf (szLine, _T(" %s %s { get; }\n"), (LPCTSTR) spFunction->GetReturnType(), (LPCTSTR) spFunction->GetName());
WriteLine (fh, szLine);
}
break;
// setter
case 4:
{
_stprintf (szLine, _T(" %s %s { set; }\n"), (LPCTSTR) spFunction->GetReturnType(), (LPCTSTR) spFunction->GetName());
WriteLine (fh, szLine);
}
break;
default:
// set a breakpoint here!
_stprintf (szLine, _T(" // %s %s // Unkown !!!"), (LPCTSTR) spFunction->GetReturnType(), (LPCTSTR) spFunction->GetName());
break;
}
}
_stprintf (szLine, _T(" };\n\n"));
WriteLine (fh, szLine);
break;
case TKIND_COCLASS:
break;
}
}
// namespace
_stprintf (szLine, _T("}\n\n"));
WriteLine (fh, szLine);
}
catch (_com_error & e)
{
hr = e.Error();
}
catch (...)
{
hr = E_FAIL;
}
if (fh != INVALID_HANDLE_VALUE)
CloseHandle (fh);
return 0;
}