2016-03-23 49 views
0

Excel'de C# kodundan Excel-DNA kullanarak bir VBA çağrısı başlatmaya çalışıyorum.Excel DNA - Marshal C# dizesi VBA ByRef geri aramada

C# Kod

[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 Modülü

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 

: Belirli veri türleri ile karıştırmasını ve beyanları marshalling sonra nihayet bir çalışma örneği oluşturmak başardı

Yukarıdaki kod örneği görebileceğiniz gibi Soru, dizeleri için varsayılan COM manevra BStr nam-ı ByVal ... As String olduğunu.

Dize verilerini (veya bu konuya ilişkin herhangi bir nesne türünü) VBA geri çağrısına ByRef iletmenin bir yolu olup olmadığını merak ettim ve eğer öyleyse, C# bildirimleri ve sıralaması özellikleri ne olmalıdır?

+0

"Ref string" denediniz mi? – Govert

+0

Eğer erken bağlayıcı bir yaklaşım kurabiliyorsanız, bir olay daha açık olacaktır (bu sizin sorunuza cevap vermeyecektir). – Govert

+0

@Govert, Buna inanamıyorum (bir grup gofre rehberi “Marshal” denedikten sonra), ama sadece “ref” anahtar kelimesini C# tarafına koymanız bunu yapar. Resmi bir cevap yaz ve kabul edeceğim. – nicholas

cevap

0

Parametrenin ref string olarak belirtilmesi gerekir.

Dize sıralama seçenekleri hakkında daha fazla bilgi için https://msdn.microsoft.com/en-us/library/s9ts558h(v=vs.110).aspx konusuna bakın.

+0

... çalışmalı ve çalışıyor. Interop marshaler bazen şaşırtıcı derecede akıllı olabilir. Not: Bu, "Marshal.StringToBSTR (..)" öğesini el ile çağırıp "IntPtr" sözcüğünü "ref" ile geçirmenin karşılığıdır. Her iki şekilde de, performans-bilge, 'ByVal' veya 'ByRef' dizesini iletmek neredeyse aynıdır, çünkü BSTR dönüşümü her zaman bir kopya oluşturur. – nicholas