2009-07-07 11 views
6

Xlcall32.dll dosyasının Excel4v işlevine çok sayıda çağrı yapmayı içeren bir XLL eklentisi oluşturmak için Delphi kullanıyorum. Ancak, burada çok az sayıda Delphi uzmanının bu özel API ile çalıştığını tahmin ettiğim için, sorunun diğer API'larda da görüldüğünü umuyorum. DelphiDelphi'den Özel Win32 API'sini Çağırma - Neden istisnalar "asm pop ..." olmadan uçar?

int pascal Excel4v(int xlfn, LPXLOPER operRes, int count, LPXLOPER opers[]); 

kullanıyorum:

function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer; 
    opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll'; 

LPXLOPER bir gösterici özellikle Microsoft Excel 2007 XLL SDK ile birlikte xlcall.h dosyasında Excel4v olarak tanımlanır C

, bir yapıya (C) veya kayıt (Delphi'de).

Delphi'de C işlevlerini bildirme üzerine ödevimi yapıyorum (this excellent article çok yardımcı oldu) ve Excel4v'yi doğru şekilde bildirdiğimi düşünüyorum. Ancak, bu işlev neden istisnalar içine Delphi kodundan çağırır onlar şu çizgi izlemektedir sürece ("erişim ihlali ..." Ben görmeye devam budur): yere tanımlanır "lavabo"

asm pop sink; end; 

bir tamsayı olarak.

Montaj hakkında hiçbir fikrim yok ... Bu yüzden istisnaları "asm pop sink; end;" ile düzeltmeyi denemem mümkün olmazdı. Ama "asm pop lavabo; sonu;" gerçekten istisnaları giderir. İlk olarak onu this useful article on making XLLs using Delphi'da kullandığını gördüm. İşte en alakalı bir alıntı:..

"Delphi'den eklentilerle büyük engel yığın dönüş adresinden sonra fazladan parametre olduğunu Bu gelir her çağrısı ile serbest Excel'e Ben ve ne kadar tuttuğunu asla bulamadınız, ama 'u attığınız sürece eklentiniz iyi çalışacaktır. satır asm pop değişkeni, sonu; her aramanın değişebileceği her çağrı global, yerel veya 'un en az 4 bayt uzunluğunda tamsayı olduğu nesne değişkeni para cezasıdır. Her Excel4v çağrısından sonra DAHİL. Aksi takdirde bir zaman bomba inşa edilmektedir . "

Temelde

Ben gerçekte neler anlamak istiyorum ve neden. Ne dönmek için bir Win32 işlevini neden olabilecek" getirisi adresinden sonra fazladan bir parametre yığını "ve aslında ne anlama geliyor?

farklı bir derleyici seçeneği veya işlevi bildirerek farklı bir şekilde örneğin bu, düzeltmek için başka bir yolu var olabilir mi?

ve eğer bir şey arama konusunda riskli yoktur" asm pop virüsü; End "Excel4v her çağrıdan sonra ...? İyi çalışıyor gibi görünüyor, ama ne olduğunu anlamıyorum gibi, biraz tehlikeli hissettiriyor ...

+0

Delphi'de bir XLL yazıyorum ve sizinle iletişim kurmak istiyorum. Lütfen bana e-posta gönderin [email protected] – garethm

cevap

8

Ben stdcall vs pascal inanmıyorum - onlar çok benzer arama kuralları ve işlev Çıkışta bir eşleşmeyen yığın neden olmamalıdır. article başvurulan itibaren

,

Bu gerçekten çok güzel bir sözdizimi olacaktır, ama bu dizi tanım yukarıda aynı değildir. dizisi parametreleri açık dizi parametreleridir. Herhangi bir dizi gibi görünebilir ve herhangi bir diziyi kabul ederler, ancak dizideki en yüksek dizini tutan ekstra (gizli) parametresi alırlar ( Yüksek değer). Bu sadece Delphi'de olduğu ve C veya C++ uygulamasında olmadığı için, 'un gerçek bir problemi olur. ( gerçek parametre sayısı eşleşmeyeceğinden, (ayrıca açık dizilerdeki makalem de bakın).

Ek "en yüksek dizi dizini" parametresine işleve iletiliyorsunuz. Bu bir int'dir ve işlev çıktığı zaman temizlenmelidir, böylece bozuk bir yığınla ve çökmeyle sarılmamalısınız. Makale, dizileri C işlevlerine nasıl geçireceğini gösterir. gibi

şey:

type 
PLPXLOPER = ^LPXLOPER; 

Ve son parametre olarak PLPXLOPER geçmektedir.

+0

Teşekkürler Michael, bana açıklama gibi geliyor :) ben emin olmak için biraz emin ol ve tekrar yorum yap. –

+0

Fantastik! Tam olarak çalıştığını söyleyebileceğim kadarıyla. işlevini Excel4v işlevi olarak tanımlayın (xlfn: Tamsayı; operRes: LPXLOPER; sayım: Tamsayı; opers: PLPXLOPER): Tamsayı; stdcall; harici 'xlcall32.dll'; sonra aramak için, LPXLOPER bir Delphi dizisi yapın ve PLPXLOPER için @ myArray [0] ile Excel4v çağırın. Stdcall ile harika çalışıyor, ve şüpheli görünümlü asm çağrılarına gerek yok :) –

0

Arama kuralınız yanlıştır, özellikle "stdcall".C Bildirisi

stdcall sol düzene hakkı parametreleri geçer rutin temizlemek için beklediğini ve kayıtlarını kullanmamaktadır "pascal" olarak belirtilir. Pascal, OTOH, parametresinden numaralı siparişi sola gönderir. Bu nedenle, kodun diğer yarısının her iki durumda da beklediği gibi bir şey olmuyor.

değiştirin Delphi bildirgesinde yerine "stdcall" nin "pascal" olmak.

+0

Bunu pascal olarak belirtmeyi denedim, ancak daha sonra çalışmak için herhangi bir çağrı almadım. Ancak işlev, "asm pop ..." satırı ile takip edilmesi şartıyla stdcall ile kesinlikle düzgün şekilde çalışıyor. Http://rvelthuis.de/articles/articles-convert.html adresindeki makale, her ne kadar spesifik olmasa da, karşı-sezgisel bir anlamı olan pascal'dan bahseder. –

+0

Farklı çağrı kuralları olarak kullanılıyorlardı. Günümüzde "pascal", C başlıklarında "stdcall" anlamına gelen bir makrodur. –

+0

Ben de PASCAL # olarak tanımladı __stdcall için de. . . ama delphi'ye göre ne anlama geldiğinden emin değilim. Orijinal düşüncem aynı zamanda çağrı çağrısı uyuşmuyordu, ancak böyle bir işlev için çağrı, arayan-kaydetme ve aranan-kaydetme kuralları arasında sadece 4 bayt tarafından kapatılmayacaktı. http://msdn.microsoft.com/en-us/library/wda6h6df(VS: – Michael

İlgili konular