Summer-Time
Summer-Time

Reputation: 1874

Access VBA functions from C#

im currently playing around with events. But unfortunately latebinding in VBA doesn't support Events. So I'm using AddressOf. Within Access/Excel (my App) it works fine (see link)

Calling from C# the Text is returning "??" instead of the correct text

Thanks, Andi

    public delegate void CallbackMsg(string msg, int unused1, int unused2, int unused3);

    [ComVisible(true)]
    public void TestProcess(int callback)
    {

        CallbackMsg x = (CallbackMsg)Marshal.GetDelegateForFunctionPointer(new IntPtr(callback), typeof(CallbackMsg));
        x.Invoke("Hello Office", 0, 0, 0);

        System.Windows.Forms.MessageBox.Show("Test DOTNET");
    }

Upvotes: 2

Views: 832

Answers (1)

LEADTOOLS Support
LEADTOOLS Support

Reputation: 2775

The strings used internally inside VB are neither C-style null-terminated strings nor "standard" Unicode strings. They are a special structure named BSTR (Basic Strings).

C# has a way of working with them through the Marshal class, so the C# code will look like this:

public delegate void CallbackMsg(IntPtr bstrMsg, int unused1, int unused2, int unused3);

[ComVisible(true)]
public void TestProcess(int callback)
{
   IntPtr ptrBSTR = Marshal.StringToBSTR("Hello Office");
   CallbackMsg x = (CallbackMsg)Marshal.GetDelegateForFunctionPointer(new IntPtr(callback), typeof(CallbackMsg));
   x.Invoke(ptrBSTR, 2, 4, 6);
   Marshal.FreeBSTR(ptrBSTR); //MUST free it
}

I tested this with Excel 2010, but I think it would be the same with other VBA products. The VBA code looks like this:

Public Sub CallbackMsg(ByVal s As String, ByVal unused1 As Long, ByVal unused2 As Long, ByVal unused3 As Long)
   Debug.Print "This string came from C#: "; s
   Debug.Print unused1, unused2, unused3
End Sub

Sub TestComVisbl()
   Dim o As Object
   Set o = CreateObject("ComVisbl.Class1")
   Call o.TestProcess(AddressOf CallbackMsg)
End Sub

Upvotes: 2

Related Questions