2010-07-13 17 views
7

Bir Native.dll dosyasında bir C++ yöntemi int NativeMethod(double, double *) olduğunu varsayalım. Yönetilen koddan bu yöntemin çağrılması benim ilk denemem DLL kullanmak SonraDllImport'un doğru kullanımı

[DllImport("Native.dll")] 
private static extern int NativeMethod(double inD, IntPtr outD); 

(I giriş noktası belirtmeniz gerekmez varsayarak) oldu yaptım

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); 
NativeMethod(2.0, x); 

//do stuff with x 

Marshal.FreeHGlobal(x); //crash 

ben anlamak istiyorum Bu neden burada çöküyor. Benim ilk tahminim DLL ve benim uygulama farklı bir CRT kullanıyor olabilir gerçeğini nedeniyle bir yığın sorun olmasıdır. Ama durum buysa, neden NativeMethod çökmesine çağrı yapmıyor? Yöntem, double'ı başarılı bir şekilde çıkarabileceğim bir x döndürdü. Ben ithalat

[DllImport("Native.dll")] 
private static extern int NativeMethod(double inD, IntPtr outD); 

referans

tarafından çift geçirerek işe almak mümkün

Neden ilk girişimde FreeHGlobal kazasında, ve yerli yöntemlere işaretçileri geçmesi için önerilen yol mu ne? Dışarıdaki anahtar kelime bu durumu iyi bir şekilde yerine getirebilir, ancak eğer Marshal'e bir ipe ihtiyacım olursa?

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double))); 
+0

Size verdiği hata iletisi nedir? – Amy

+0

Elbette, bu tip (çift) olmalıdır. Ama bence BoyOf (typp (InpPtr)) her zaman = = SizeOf (typeof (double)), bu yüzden bir şekilde işe yarayabilir. İlginç, "x ile şeyler" kısmı nedir? –

cevap

5

sorun yöntemidir bir double* alır ki: Ben uzmanı değilim, ama bu olmamalı ... Ben AllocH ve Freeh etrafında alabilirsiniz

+0

Ah, çok teşekkürler .. msdn referansında platforma özgü boyut ile ilgili kısmı özledim. En temsilci – insipid

2

sanmıyorum bir çift için bir işaretçi. IntPtr işaret eden bir işaretçiyi geçiyorsunuz. Bu sadece, double (8 bayt) ve değişken boyutta (4 veya 8 bayt) olan IntPtr arasında bir boyut farkı olması bakımından önemlidir. Ben senin hedefe yanlış anlama olabilecek bir double

IntPtr x = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)); 
7

işaretçiyi tahsis etmek gerekir, ancak o gereğinden daha daha karmaşık yapıyoruz görünüyor. Sadece referans ile iletin ve alt kısımdaki sıralamanın onu ele almasına izin verin.

[DllImport("Native.dll")] 
private static extern int NativeMethod(double inD, ref double outD); 

double x; 

x = 1; 
NativeMethod(2.0, ref x); 
+0

+1 yerine ref yerine kullanmak olacaktır. OP, işaretçiyi hiç başlatmadı. – JaredPar

+0

@JaredPar, bu doğru. OP'nin ref veya out davranışı istediği konusunda emin değildim, ancak bu açık ipucunu (örnekte başlatmadığı gerçeğini) anlayamadım. –

+0

Tam/ref vs AllocHGlobal'in kullanılmamış belleğe ulaşmasının nasıl bir etkisi var? GC yöntem/işlev geri gelmeden önce belleği yeniden düzenleyebilir ve işaretçi referanslarını değiştirebilir mi? –

İlgili konular