Because C# does not provide a dllexport equivalent, you'll need to add a CPP shim into the mix that can get an instance of the managed class from the CLR. Here's the quick walkthrough:
1. Add a cpp library to the VSTA integration solution
2. Reference the VSTA Integration assembly from the cpp library project
3. Define a dllexport
4. Implement the dllexport
5. LoadLibrary on the cppdll
6. GetProcAddress of the exported func
7. Create a typedeclaration for the exported func signature
8. Call it
Here is the unmanaged CPP app code:
typedef void *(__stdcall _CreateInstance)(void);
typedef _CreateInstance *RTCCREATEINSTANCEPROC;
static RTCCREATEINSTANCEPROC lpfnRtcCreateInstance = NULL;
HMODULE hm = LoadLibrary(OLESTR("CppClassLibrary1.dll"));
if (hm != N ULL)
{
lpfnRtcCreateInstance = (RTCCREATEINSTANCEPROC)GetProcAddress(hm, "CreateInstance");
void *managedinterface = (*lpfnRtcCreateInstance)();
FreeLibrary(hm);
}
Here's the C# code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[ComVisible(true)]
public interface Interface1
{
string HelloWorld { get; }
}
[ComVisible(true)]
public class Class1 : Interface1
{
#region Interface1 Members
public string HelloWorld
{
get
{
return "Hello World!";
}
}
#endregion
public static IntPtr CreateInstance()
{
return Marshal.GetComInterfaceForObject(new Class1(), typeof(Interface1));
}
}
}
Here's the CPP shim code (that matters):
void *CreateInstance()
{
return (void *)ClassLibrary1::Class1().CreateInstance();
}
Here's the .def code:
LIBRARY "CppClassLibrary1"
EXPORTS
CreateInstance @1
Make sure that the C# types are marked ComVisible(True). You should be able to cast the void * to the interface definition (they should be the same on either side...)