Ich versuche, einen VBA-Callback in Excel aus C# -Code mit Excel-DNA aufzurufen. um mit den speziellen Datentypen Nach Messing und Rangier-Erklärungen, konnte ich endlich eine Arbeitsprobe erstellen:Excel DNA - Marshal C# Zeichenfolge zu VBA ByRef in Rückruf
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-Modul
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
Frage
Wie Sie aus dem Codebeispiel oben sehen können, die Standard-COM-Rangierung für Strings ist BStr
auch bekannt als ByVal ... As String
.
Ich frage mich, ob es eine Möglichkeit gibt, Zeichenfolgedaten (oder einen beliebigen anderen Objekttyp) an den VBA-Callback weiterzugeben, und wenn ja, wie würden die C# -Deklarationen und Marshalling-Attribute aussehen?
Haben Sie 'ref string' probiert? – Govert
Wenn Sie einen frühbindenden Ansatz wählen können, wäre ein Ereignis einfacher (obwohl das Ihre Frage nicht behandeln würde). – Govert
@ Govert, ich kann es nicht glauben (nach dem Versuch, ein paar doof manuelle 'Marshal'-Aufrufe), aber einfach das' Ref'-Schlüsselwort auf der C# Seite setzen tut es. Schreiben Sie eine formelle Antwort auf, und ich werde es akzeptieren. – nicholas