Search code examples
c#vbacomexcel-dna

Excel DNA - Marshal C# string to VBA ByRef in callback


I am attempting to invoke a VBA callback in Excel from C# code using Excel-DNA. After messing around with the particular data types and marshalling declarations, I was able to finally create a working sample:

C# Code

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ProgId("CSharpComObject")]
public partial class CSharpComObject
{
    Dictionary<string, Callback> _callbackMap = new Dictionary<string, Callback>();


    public void SubscribeStringData(string topic, [MarshalAs(UnmanagedType.FunctionPtr)] Callback callback)
    {
        _callbackMap[topic] = callback;
    }

    public void RaiseCallback(string topic, string data)
    {
        _callbackMap[topic](data);
    }

    public delegate void Callback([MarshalAs(UnmanagedType.BStr)] string data);
}

VBA Module

Option Explicit

Dim testObj As Object



Sub Subscribe()

Set testObj = CreateObject("CSharpComObject")

testObj.SubscribeStringData "someTopic", AddressOf StringDataCallback

End Sub



Sub StringDataCallback(ByVal data As String)

MsgBox "StringDataCallback Raised [" + data + "]"

End Sub

Question

As you can see from the code sample above, the default COM marshalling for strings is BStr a.k.a. ByVal ... As String.

I was wondering if there is a way to pass string data (or any object type for that matter) to the VBA callback ByRef, and if so, what would the C# declarations and marshalling attributes need to be?


Solution

  • Specifying the parameter as ref string should work.

    See https://msdn.microsoft.com/en-us/library/s9ts558h(v=vs.110).aspx for more information about the string marshaling options.