Я пытаюсь вызвать обратный вызов VBA в Excel из кода C# с использованием Excel-DNA. После возни с конкретными типами данных и сортировочных декларации, я смог, наконец, создать рабочую пробу:Excel DNA - Marshal C# string для VBA ByRef в обратном вызове
C# Код
[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 модуль
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
Вопрос
Как вы можете видеть из приведенного выше примера кода, COM-сортировка по умолчанию для строк равна BStr
a.k.a. ByVal ... As String
.
Мне было интересно, если есть способ передать строковые данные (или любой тип объекта, если на то пошло) на обратный вызов VBA ByRef
, и если да, то какими должны быть объявления C# и атрибуты маршаллинга?
Вы пробовали 'ref string'? – Govert
Если вы можете принять ранний подход, событие будет более простым (хотя это не будет решать ваш вопрос). – Govert
@ Govert, я не могу в это поверить (попробовав кучу дурацких ручных 'Marshal'), но просто поместите ключевое слово' ref' на стороне C#. Напишите официальный ответ, и я приму его. – nicholas