Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Enteroperabilite marshalingi, yöntem parametreleriyle ilişkili verilerin yönetilen ve yönetilmeyen bellek arasında geçerken nasıl davranacağını belirleyen kurallar doğrultusunda işler. Bu yerleşik kurallar veri türü dönüştürmeleri gibi sıralama etkinliklerini, çağıranın geçirilen verileri değiştirip değiştiremeyeceğini ve bu değişiklikleri çağırana döndürebileceğini ve hangi koşullarda marshaller'ın performans iyileştirmeleri sağladığını denetler.
Bu bölümde birlikte çalışma marshalling hizmetinin varsayılan davranışsal özellikleri tanımlanır. Dizileri hizalama, Boole türleri, karakter türleri, temsilciler, sınıflar, nesneler, dizeler ve yapılar hakkında ayrıntılı bilgiler sunar.
Uyarı
Genel türlerin yapılandırılması desteklenmez. Daha fazla bilgi için bkz. Genel Türleri Kullanarak Birlikte Çalışma.
Birlikte çalışma yardımcısı ile bellek yönetimi
Interop marshaller her zaman yönetilmeyen kod tarafından ayrılan belleği boşaltmaya çalışır. Bu davranış COM bellek yönetimi kurallarıyla uyumlu olsa da yerel C++'ı yöneten kurallardan farklıdır.
Platform çağrısı kullanılırken yerel C++ davranışını (bellek boşaltma olmadan) tahmin ederseniz karışıklık oluşabilir ve bu da işaretçiler için belleği otomatik olarak boşaltabilir. Örneğin, C++ DLL'den aşağıdaki yönetilmeyen yöntemi çağırmak hiçbir belleği otomatik olarak boşaltmaz.
Yönetilmeyen imza
BSTR MethodOne (BSTR b) {
return b;
}
Ancak, yöntemi bir platform çağırma prototipi olarak tanımlarsanız, her BSTR türünü bir String türle değiştirin ve MethodOne
çağırın, ortak dil çalışma zamanı b
'ü iki kez boşaltmaya çalışır.
IntPtr türlerini kullanarak Dize türlerinin yerine sıralama davranışını değiştirebilirsiniz.
Çalışma zamanı, belleği boşaltmak için her zaman Windows'ta CoTaskMemFree yöntemini ve diğer platformlarda ücretsiz yöntemini kullanır. Üzerinde çalıştığınız bellek Windows'ta CoTaskMemAlloc yöntemiyle veya diğer platformlarda malloc yöntemiyle ayrılmadıysa, intPtr kullanmanız ve uygun yöntemi kullanarak belleği el ile boşaltmanız gerekir. Benzer şekilde, çekirdek belleğine bir işaretçi döndüren Kernel32.dllGetCommandLine işlevini kullanırken olduğu gibi, belleğin hiçbir zaman boşaltılmaması gereken durumlarda otomatik bellek boşaltmayı önleyebilirsiniz. Buffers Örneği'ne bakın: Belleği el ile boşaltma hakkında ayrıntılı bilgi için.
Sınıflar için varsayılan sıralama
Sınıflar yalnızca COM birlikte çalışması kullanılarak manage edilebilir ve her zaman arabirimler olarak manage edilir. Bazı durumlarda sınıfını sıralamak için kullanılan arabirim, sınıf arabirimi olarak bilinir. Sınıf arabirimini seçtiğiniz bir arabirimle geçersiz kılma hakkında bilgi için bkz. Sınıf arabirimini tanıtma.
Sınıfları COM'a Geçirme
Yönetilen bir sınıf COM'a geçirildiğinde, ara dil marshaler sınıfı otomatik olarak bir COM proxy'si aracılığıyla sarar ve proxy tarafından oluşturulan sınıf arabirimini COM yöntemi çağrısına iletir. Ardından proxy, sınıf arabirimindeki tüm çağrıları yönetilen nesneye geri gönderir. Proxy ayrıca sınıfı tarafından açıkça uygulanmayan diğer arabirimleri de kullanıma sunar. Ara sunucu, sınıf adına IUnknown ve IDispatch gibi arabirimleri otomatik olarak uygular.
Sınıfları .NET Code'a Geçirme
Ortak sınıflar genellikle COM'da yöntem bağımsız değişkenleri olarak kullanılmaz. Bunun yerine, genellikle coclass yerine varsayılan bir arabirim geçirilir.
Bir arayüz yönetilen koda aktarıldığında, birlikte çalışabilirlik düzenleyicisi arayüzü uygun sarmalayıcı ile sarmalayarak ve bu sarmalayıcıyı yönetilen metoda ileterek işlem yapar. Hangi sarmalayıcının kullanılacağını belirlemek zor olabilir. Bir COM nesnesinin her örneği, nesnenin kaç arabirim uyguladığı fark etmez, tek, benzersiz bir sarmalayıcıya sahiptir. Örneğin, beş ayrı arabirim uygulayan tek bir COM nesnesi yalnızca bir sarmalayıcıya sahiptir. Aynı kapsayıcı tüm beş arabirimi kullanıma sunar. COM nesnesinin iki örneği oluşturulursa sarmalayıcının iki örneği oluşturulur.
Sarmalayıcının yaşam süresi boyunca aynı türe sahip olması için, birlikte çalışma başlatıcısı, nesne tarafından kullanıma sunulan bir arabirim ilk kez marshaller aracılığıyla geçirildiğinde doğru sarmalayıcıyı tanımlamalıdır. Marshaller, nesnenin uyguladığı arabirimlerden birine bakarak nesneyi tanımlar.
Örneğin, düzenleyici, sınıf sarmalayıcının, yönetilen kodda geçirilen arabirimi sarmak için kullanılması gerektiğini belirler. Arabirim, marshaller aracılığıyla ilk geçirildiğinde, marshaller arabirimin bilinen bir nesneden gelip gelmediğini denetler. Bu denetim iki durumda gerçekleşir:
Arabirim, başka bir yerde COM'a geçirilen başka bir yönetilen nesne tarafından uygulanıyor. Marshaller, yönetilen nesneler tarafından kullanıma sunulan arabirimleri kolayca tanımlayabilir ve arabirimi uygulamayı sağlayan yönetilen nesneyle eşleştirebilir. Ardından yönetilen nesne yöntemine geçirilir ve sarmalayıcı gerekmez.
Zaten sarmalanmış olan bir nesne arabirimi uyguluyor. Bu durumun söz konusu olup olmadığını belirlemek için, marshaller nesnesini IUnknown arabirimi için sorgular ve döndürülen arabirimi zaten sarmalanmış olan diğer nesnelerin arabirimleriyle karşılaştırır. Arabirim başka bir sarmalayıcıyla aynıysa, nesneler aynı kimliğe sahiptir ve mevcut sarmalayıcı yöntemine geçirilir.
Arabirim bilinen bir nesneden değilse, marshaller aşağıdakileri yapar:
Marshaller, nesne üzerinde IProvideClassInfo2 arabirimini sorgular. Sağlanırsa, marshaller arabirimi sağlayan ortak sınıfı tanımlamak için IProvideClassInfo2.GetGUID'den döndürülen CLSID'yi kullanır. CLSID ile, derleme daha önce kaydedilmişse, marshaller sarmalayıcıyı kayıt defterinden bulabilir.
Marshaller, IProvideClassInfo arabirimini sorgular. Sağlanırsa, marshaller arabirimini ortaya çıkartan sınıfın CLSID'sini belirlemek için IProvideClassInfo.GetClassinfo'dan döndürülen ITypeInfo'yu kullanır. Marshaller sarmalayıcının meta verilerini bulmak için CLSID'yi kullanabilir.
Marshaller hala sınıfını tanımlayamıyorsa, arabirimini System.__ComObject adlı genel bir sarmalayıcı sınıfıyla sarmalar.
Temsilciler için varsayılan sıralama
Yönetilen temsilci, çağrı mekanizmasına göre COM arabirimi veya fonksiyon göstergesi olarak iliştirilir.
Platform çağrısı için, temsilci varsayılan olarak yönetilmeyen işlev işaretçisi olarak sıralanır.
COM birlikte çalışması için, bir temsilci varsayılan olarak _Delegate türünde bir COM arabirimi olarak marshallenir. _Delegate arabirimi Mscorlib.tlb tür kitaplığında tanımlanır ve temsilcinin Delegate.DynamicInvoke başvuracağı yöntemi çağırmanızı sağlayan yöntemini içerir.
Aşağıdaki tabloda yönetilen temsilci veri türü için sıralama seçenekleri gösterilmektedir. MarshalAsAttribute özniteliği, temsilcileri düzenlemek için birkaç UnmanagedType numaralandırma değeri sağlar.
Numaralandırma türü | Yönetilmeyen biçimin açıklaması |
---|---|
UnmanagedType.FunctionPtr | Yönetilmeyen işlev işaretçisi. |
UnmanagedType.Interface | Mscorlib.tlb dosyasında tanımlandığı gibi _Delegate türünde bir arabirim. |
Yöntemlerinin DelegateTestInterface
com türü kitaplığına aktarıldığı aşağıdaki örnek kodu göz önünde bulundurun. Yalnızca ref (veya ByRef) anahtar sözcüğüyle işaretlenmiş temsilcilerin In/Out parametreleri olarak geçirildiğini unutmayın.
using System;
using System.Runtime.InteropServices;
public interface DelegateTest {
void m1(Delegate d);
void m2([MarshalAs(UnmanagedType.Interface)] Delegate d);
void m3([MarshalAs(UnmanagedType.Interface)] ref Delegate d);
void m4([MarshalAs(UnmanagedType.FunctionPtr)] Delegate d);
void m5([MarshalAs(UnmanagedType.FunctionPtr)] ref Delegate d);
}
Tip kütüphanesi temsili
importlib("mscorlib.tlb");
interface DelegateTest : IDispatch {
[id(…)] HRESULT m1([in] _Delegate* d);
[id(…)] HRESULT m2([in] _Delegate* d);
[id(…)] HRESULT m3([in, out] _Delegate** d);
[id()] HRESULT m4([in] int d);
[id()] HRESULT m5([in, out] int *d);
};
Bir işlev işaretçisinin başvurusu, tıpkı yönetilmeyen işlev işaretçilerinin başvurusu kaldırılabildiği gibi kaldırılabilir.
Bu örnekte, iki temsilci UnmanagedType.FunctionPtr olarak düzenlendiğinde, sonuç bir int
ve bir int
işaretçisi olur. Temsilci türleri düzenlendiği için, int
burada bellekteki temsilcinin adresini gösteren bir void (void*
) işaretçisini gösterir. Başka bir deyişle, bu sonuç 32 bit Windows sistemlerine özgüdür, çünkü int
burada işlev işaretçisinin boyutu gösterilir.
Uyarı
Yönetilmeyen kod tarafından tutulan bir yönetilen temsilciye ait işlev işaretçisine yapılan başvuru, ortak dil çalışma zamanının yönetilen nesnede çöp toplama gerçekleştirmesini engellemez.
Örneğin, aşağıdaki kod yanlıştır çünkü cb
nesnesine yapılan referans, SetChangeHandler
yöntemine geçirilen cb
, SetChangeHandler
yönteminin ömrü ötesinde nesnesini canlı tutmaz.
cb
nesne çöp toplama işlemi tamamlandığında, SetChangeHandler
işlev işaretçisi geçerliliğini kaybeder.
public class ExternalAPI {
[DllImport("External.dll")]
public static extern void SetChangeHandler(
[MarshalAs(UnmanagedType.FunctionPtr)]ChangeDelegate d);
}
public delegate bool ChangeDelegate([MarshalAs(UnmanagedType.LPWStr) string S);
public class CallBackClass {
public bool OnChange(string S){ return true;}
}
internal class DelegateTest {
public static void Test() {
CallBackClass cb = new CallBackClass();
// Caution: The following reference on the cb object does not keep the
// object from being garbage collected after the Main method
// executes.
ExternalAPI.SetChangeHandler(new ChangeDelegate(cb.OnChange));
}
}
Beklenmeyen çöp toplamayı telafi etmek için, çağıranın, yönetilmeyen işlev işaretçisi kullanımda olduğu sürece nesne cb
canlı tutulmasını sağlaması gerekir. İsteğe bağlı olarak, aşağıdaki örnekte gösterildiği gibi, yönetilmeyen kodun artık işlev işaretçisine gerek kalmadığında yönetilen kodu bildirmesini sağlayabilirsiniz.
internal class DelegateTest {
CallBackClass cb;
// Called before ever using the callback function.
public static void SetChangeHandler() {
cb = new CallBackClass();
ExternalAPI.SetChangeHandler(new ChangeDelegate(cb.OnChange));
}
// Called after using the callback function for the last time.
public static void RemoveChangeHandler() {
// The cb object can be collected now. The unmanaged code is
// finished with the callback function.
cb = null;
}
}
Değer türleri için varsayılan sıralama
Tamsayılar ve kayan noktalı sayılar gibi çoğu değer türü blittable'dır ve sıralama gerektirmez. Diğer blittable olmayan türlerin yönetilen ve yönetilmeyen bellekte farklı gösterimleri bulunur ve bu türler için marshaling işlemi gereklidir. Yine de diğer türler, birlikte çalışma sınırı boyunca açık biçimlendirme gerektirir.
Bu bölüm, aşağıdaki biçimlendirilmiş değer türleri hakkında bilgi sağlar:
Bu konu, biçimlendirilmiş türleri açıklamaya ek olarak sıra dışı sıralama davranışına sahip Sistem Değeri Türlerini tanımlar.
Biçimlendirilmiş tür, bellekteki üyelerinin düzenini açıkça denetleyen bilgiler içeren karmaşık bir türdür. Üye düzeni bilgileri StructLayoutAttribute özniteliği kullanılarak sağlanır. Düzen aşağıdaki LayoutKind numaralandırma değerlerinden biri olabilir:
LayoutKind.Auto
Ortak dil çalışma zamanı, tür üyelerini verimlilik için serbestçe yeniden düzenleyebileceğini ifade eder. Ancak, yönetilmeyen koda bir değer türü geçirildiğinde, üyelerin düzeni tahmin edilebilir. Böyle bir yapıyı otomatik olarak hazırlama girişimi bir istisnaya neden olur.
LayoutKind.Sequential
Türün üyelerinin yönetilmeyen bellekte yönetilen tür tanımında göründükleri sırayla yerleştirileceklerini gösterir.
LayoutKind.Explicit
Üyelerin her alana sağlanan FieldOffsetAttribute değerlerine göre düzenlendiğini gösterir.
Platform Çağırmada Kullanılan Değer Türleri
Aşağıdaki örnekte Point
ve Rect
türleri , StructLayoutAttribute kullanarak üye düzeni bilgilerini sağlar.
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> Public Structure Point
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Explicit)> Public Structure Rect
<FieldOffset(0)> Public left As Integer
<FieldOffset(4)> Public top As Integer
<FieldOffset(8)> Public right As Integer
<FieldOffset(12)> Public bottom As Integer
End Structure
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}
[StructLayout(LayoutKind.Explicit)]
public struct Rect {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}
Yönetilmeyen koda aktarılırken, bu biçimlendirilmiş türler C stili yapılar olarak biçimlendirilir. Bu, yapı bağımsız değişkenleri olan yönetilmeyen bir API'yi çağırmanın kolay bir yolunu sağlar. Örneğin, POINT
ve RECT
yapıları Aşağıdaki gibi Microsoft Windows API PtInRect işlevine geçirilebilir:
BOOL PtInRect(const RECT *lprc, POINT pt);
Aşağıdaki platform çağırma tanımını kullanarak yapıları geçirebilirsiniz:
Friend Class NativeMethods
Friend Declare Auto Function PtInRect Lib "User32.dll" (
ByRef r As Rect, p As Point) As Boolean
End Class
internal static class NativeMethods
{
[DllImport("User32.dll")]
internal static extern bool PtInRect(ref Rect r, Point p);
}
Rect
türünün başvuru ile geçirilmesi gerekmektedir çünkü yönetilmeyen API, fonksiyona bir RECT
işaretçisi geçirmeyi beklemektedir.
Point
değeri, yönetilmeyen API'nin POINT
yığına geçirilmesini beklemesi nedeniyle değere göre aktarılır. Bu ince fark çok önemlidir. Referanslar yönetilmeyen koda işaretçi olarak geçirilir. Değerler yığındaki yönetilmeyen koda geçirilir.
Uyarı
Biçimlendirilmiş bir tür yapı olarak sıralandığında, yalnızca türün içindeki alanlara erişilebilir. Türün yöntemleri, özellikleri veya olayları varsa yönetilmeyen koddan erişilemez.
Sınıflar, sabit üye düzenine sahip olmaları koşuluyla, yönetilmeyen kodlara C stili yapılar olarak da sıralanabilir. Sınıfın üye düzeni bilgileri StructLayoutAttribute özniteliği aracılığıyla sağlanır. Sabit düzen içeren değer türleri ile sabit düzenli sınıflar arasındaki temel fark, yönetilmeyen koda göre düzenlenme şeklidir. Değer türleri değere (yığında) göre geçirilir ve sonuç olarak çağıran tarafından türün üyelerinde yapılan değişiklikler çağıran tarafından görülmez. Referans türleri referansa göre geçirilir (yığında türe bir referans geçirilir); sonuç olarak, çağıranın blittable türü üyelerinde yaptığı tüm değişiklikler arayan tarafından görülür.
Uyarı
Bir başvuru türü, bölünebilir olmayan türlerin üyelerine sahipse, dönüştürme iki kez gereklidir: bağımsız değişken yönetilmeyen tarafa ilk kez geçirildiğinde ve ikinci kez çağrıdan döndürüldüyse. Bu ek yük nedeniyle, çağıran, çağrılan tarafından yapılan değişiklikleri görmek istiyorsa, bir bağımsız değişkene Giriş/Çıkış parametrelerini açık bir şekilde uygulamalıdır.
Aşağıdaki örnekte, SystemTime
sınıfı sıralı üye düzenine sahiptir ve Windows API GetSystemTime işlevine geçirilebilir.
<StructLayout(LayoutKind.Sequential)> Public Class SystemTime
Public wYear As System.UInt16
Public wMonth As System.UInt16
Public wDayOfWeek As System.UInt16
Public wDay As System.UInt16
Public wHour As System.UInt16
Public wMinute As System.UInt16
Public wSecond As System.UInt16
Public wMilliseconds As System.UInt16
End Class
[StructLayout(LayoutKind.Sequential)]
public class SystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
GetSystemTime işlevi aşağıdaki gibi tanımlanır:
void GetSystemTime(SYSTEMTIME* SystemTime);
GetSystemTime için eşdeğer platform çağırma tanımı aşağıdaki gibidir:
Friend Class NativeMethods
Friend Declare Auto Sub GetSystemTime Lib "Kernel32.dll" (
ByVal sysTime As SystemTime)
End Class
internal static class NativeMethods
{
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
internal static extern void GetSystemTime(SystemTime st);
}
Bağımsız değişkenin SystemTime
bir değer türü değil, bir sınıf olduğundan SystemTime
başvuru bağımsız değişkeni olarak yazılmadığına dikkat edin. Değer türlerinden farklı olarak, sınıflar her zaman referans olarak geçirilir.
Aşağıdaki kod örneği, Point
adlı bir yöntemi olan farklı bir SetXY
sınıfını göstermektedir. Türün ardışık düzeni olduğundan, yönetilmeyen kodlara aktarılabilir ve yapı olarak dönüştürülebilir. Ancak, SetXY
nesne başvuruyla geçirilse bile üye yönetilmeyen koddan çağrılamaz.
<StructLayout(LayoutKind.Sequential)> Public Class Point
Private x, y As Integer
Public Sub SetXY(x As Integer, y As Integer)
Me.x = x
Me.y = y
End Sub
End Class
[StructLayout(LayoutKind.Sequential)]
public class Point {
int x, y;
public void SetXY(int x, int y){
this.x = x;
this.y = y;
}
}
COM Birlikte Çalışmasında Kullanılan Değer Türleri
Biçimlendirilmiş türler COM birlikte çalışma yöntemi çağrılarına da geçirilebilir. Aslında, bir tür kitaplığına aktarıldığında, değer türleri otomatik olarak yapılara dönüştürülür. Aşağıdaki örnekte gösterildiği gibi, Point
değer türü adlı Point
bir tür tanımına (typedef) dönüşür. Tür kitaplığındaki Point
değer türüne yapılan tüm başvurular, yerine Point
typedef geçer.
Tip kütüphanesi gösterimi
typedef struct tagPoint {
int x;
int y;
} Point;
interface _Graphics {
…
HRESULT SetPoint ([in] Point p)
HRESULT SetPointRef ([in,out] Point *p)
HRESULT GetPoint ([out,retval] Point *p)
}
COM arabirimleri aracılığıyla sıralama yaparken değerleri ve platform çağırma çağrılarına yapılan başvuruları sıralamak için kullanılan kuralların aynısı kullanılır. Örneğin, bir Point
değer türü örneği .NET Framework'ten COM'a geçirildiğinde, Point
değer olarak aktarılır.
Point
Değer türü referansla geçiriliyorsa, yığına bir Point
işaretçisi geçirilir. Etkileşim marshallerı, her iki yönde de Point ** gibi daha yüksek dolaylılık seviyelerini desteklemez.
Uyarı
Numaralandırma değeri LayoutKind olarak ayarlanmış yapılar, dışarı aktarılan tür kitaplığı açık bir düzeni ifade edemediğinden COM etkileşiminde kullanılamaz.
Sistem Değer Türleri
Ad alanı System, çalışma zamanı temel türlerinin kutuyla gösterilen biçimini temsil eden birkaç değer türüne sahiptir. Örneğin, değer türü System.Int32 yapısı ELEMENT_TYPE_I4 kutulu biçimini temsil eder. Diğer biçimlendirilmiş türler gibi bu türleri yapı olarak sıralamak yerine, bunları kutuladıkları ilkel türler gibi sıralarsınız. Bu nedenle System.Int32, long türünde tek bir üye içeren bir yapı yerine ELEMENT_TYPE_I4 olarak sıralanır. Aşağıdaki tabloda , Sistem ad alanında ilkel türlerin kutulanmış gösterimleri olan değer türlerinin listesi yer alır.
Sistem değer türü | Öğe türü |
---|---|
System.Boolean | ELEMENT_TYPE_BOOLEAN |
System.SByte | ELEMENT_TYPE_I1 |
System.Byte | ELEMENT_TYPE_UI1 |
System.Char | ELEMENT_TYPE_CHAR |
System.Int16 | ELEMENT_TYPE_I2 |
System.UInt16 | ELEMENT_TYPE_U2 |
System.Int32 | ELEMENT_TYPE_I4 |
System.UInt32 | ELEMENT_TYPE_U4 |
System.Int64 | ELEMENT_TYPE_I8 |
System.UInt64 | ELEMENT_TYPE_U8 |
System.Single | ELEMENT_TYPE_R4 |
System.Double | ELEMENT_TYPE_R8 |
System.String | ELEMENT_TYPE_STRING |
System.IntPtr | ELEMENT_TYPE_I |
System.UIntPtr | ELEMENT_TYPE_U |
Sistem ad alanı içindeki diğer bazı değer türleri farklı şekilde işlenir. Yönetilmeyen kodun bu türler için zaten iyi belirlenmiş biçimleri olduğundan, yürütücünün bunları yönetmek için özel kuralları vardır. Aşağıdaki tabloda System ad alanında özel değer türleri ve bunların aktarılacağı yönetilmeyen tür listelenmiştir.
Sistem değer türü | IDL türü |
---|---|
System.DateTime | TARİH |
System.Decimal | ONDALIK |
System.Guid | GUID |
System.Drawing.Color | OLE_COLOR |
Aşağıdaki kod, Stdole2 tür kitaplığında DATE, GUID, DECIMAL ve OLE_COLOR yönetilmeyen türlerin tanımını gösterir.
Tip kütüphanesi temsili
typedef double DATE;
typedef DWORD OLE_COLOR;
typedef struct tagDEC {
USHORT wReserved;
BYTE scale;
BYTE sign;
ULONG Hi32;
ULONGLONG Lo64;
} DECIMAL;
typedef struct tagGUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[ 8 ];
} GUID;
Aşağıdaki kod, yönetilen IValueTypes
arabirimde karşılık gelen tanımları gösterir.
Public Interface IValueTypes
Sub M1(d As System.DateTime)
Sub M2(d As System.Guid)
Sub M3(d As System.Decimal)
Sub M4(d As System.Drawing.Color)
End Interface
public interface IValueTypes {
void M1(System.DateTime d);
void M2(System.Guid d);
void M3(System.Decimal d);
void M4(System.Drawing.Color d);
}
Tip kütüphanesi temsili
[…]
interface IValueTypes : IDispatch {
HRESULT M1([in] DATE d);
HRESULT M2([in] GUID d);
HRESULT M3([in] DECIMAL d);
HRESULT M4([in] OLE_COLOR d);
};