2
votes

To avoid requiring a Dll be registered for all users of a spreadsheet, I'm trying to use late binding so that users do not need to add a reference to the Dll.

I've created the Dll in C# with Visual Studio, and even though I've included "using RGiesecke.DllExport;" and used DllExport on a function to return an object containing the functions I need to access in VBA, I still get the error "Run-time error '453': Can't Find DLL entry point CreateDotNetObject in C:\temp\MyFunctions.dll."

The DLL code is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Data;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Client;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections;
using System.Collections.ObjectModel;
using System.Threading;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework;
using Microsoft.TeamFoundation.Common;
using Microsoft.VisualBasic;
using System.Diagnostics;
using RGiesecke.DllExport;

namespace MyFunctions
{
    public interface IMyFunctions
    {
        string GetWorkItemLinkList(string WIIDs);
    }

    [CLSCompliant(true), ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyFunctions : IMyFunctions
    {
        TfsConfigurationServer server;
        WorkItemStore store;

        private void TFSconnect()
        {
        //Code to connect
        }

        [CLSCompliant(true), ComVisible(true), Description("GetWorkItemLink func")]
        public string GetWorkItemLink(int WIID)
        {
            TFSconnect();

        //Code to build return string "message"

            return message;
        }



        [CLSCompliant(true), ComVisible(true), Description("GetWorkItemLinkList func")]
        public string GetWorkItemLinkList(string WIIDs)
        {
            TFSconnect();

        //Code to build return string "returnStr"

            return returnStr;
        }


    }
    static class UnmanagedExports
    {
        [DllExport]
        [return: MarshalAs(UnmanagedType.IDispatch)]
        static Object CreateDotNetObject()
        {
            return new MyFunctions();
        }
    }
}

and the declaration in VBA is as follows:

Private Declare Function CreateDotNetObject Lib "c:\temp\MyFunctions.dll" () As Object

But when I try to instantiate an object, I get the error I mentioned above.

Sub test()

    Dim o As Object
    Set o = CreateDotNetObject()

End Sub

This is my first time attempting to use custom dll functions in Excel without adding a reference in the VBA. The functions do work if I add a reference (early binding), but the DLL is not going to be propogated to everyone who uses the spreadsheet, and I need it to not crash when they run normal functions.

EDIT: Additional info. I just noticed that in addition to the DLL, when I build the solution in Visual Studio I also get an " Object FileLibrary" and an "Exports Library File". When I register the DLL is there anything I should be doing with either the .exp or .lib?

Thanks,

Mike

1
I have only ever got this to work using c++, not c#. I can post that code if it helps?steveo40
From what i understand, in C++ you can use __declspec( dllexport ) declarator and it's easier to use, but the DLLExport by RGiesecke is the work-around for C#. I could probably re-write the DLL in C++, but since the functions work as the are if I include a reference in Excel, I'm hoping there's some small syntax issue in my code that could be easier than rewriting in C++. But maybe it might be helpful.IoTMike

1 Answers

3
votes

I was building the solution with the Platform Target in the class library properties set to "Any PC", which apparently does not allow exports. When I switch it to "x86" it totally works.