Sử dụng các tệp nguồn giống hệt nhau cho Fortran .dll tôi có thể biên dịch chúng bằng Compaq Visual Fortran 6.6C hoặc Intel Visual Fortran 12.1.3.300 (IA-32). Vấn đề là việc thực hiện thất bại trên nhị phân Intel, nhưng hoạt động tốt với Compaq. Tôi đang biên dịch 32 bit trên hệ thống Windows 7 64 bit. Trình điều khiển cuộc gọi .dll được viết bằng C#
.Ngăn xếp tràn trên cuộc gọi chương trình con chỉ khi được biên dịch với Intel Visual Fortran và tiền phạt khi biên dịch bởi Compaq Visual Fortran
Thông báo lỗi đến từ cuộc gọi _chkstk()
đáng sợ khi một chương trình con nội bộ được gọi (được gọi từ thường trình nhập .dll). (SO trả lời trên chkstk()
)
Thủ tục trong câu hỏi được khai báo là (tha thứ các định dạng tập tin cố định)
SUBROUTINE SRF(den, crpm, icrpm, inose, qeff, rev,
& qqmax, lvtyp1, lvtyp2, avespd, fridry, luin,
& luout, lurtpo, ludiag, ndiag, n, nzdepth,
& unit, unito, ier)
INTEGER*4 lvtyp1, lvtyp2, luin, luout, lurtpo, ludiag, ndiag, n,
& ncp, inose, icrpm, ier, nzdepth
REAL*8 den, crpm, qeff, rev, qqmax, avespd, fridry
CHARACTER*2 unit, unito
và kêu gọi như thế này:
CALL SRF(den, crpm(i), i, inose, qeff(i), rev(i),
& qqmax(i), lvtyp1, lvtyp2, avespd, fridry,
& luin, luout, lurtpo, ludiag, ndiag, n, nzdepth,
& unit, unito, ier)
với thông số kỹ thuật biến tương tự trừ crpm
, qeff
, rev
và qqmax
là các mảng chỉ sử dụng các thành phần i-th
cho mỗi cuộc gọi SRF()
.
Tôi hiểu các vấn đề có thể xảy ra nếu đối số có kích thước lớn hơn 8kb
, nhưng trong trường hợp này, chúng tôi chỉ có đối số được chuyển là 7 x real(64) + 11 x int(32) + 2 x 2 x char(8) = 832 bits
.
Tôi đã làm việc thực sự khó khăn để di chuyển đối số (đặc biệt là mảng) vào một mô-đun, nhưng tôi vẫn gặp lỗi tương tự
.
Các dissasembly từ .dll Intel là
Các dissasembly từ Compaq .dll là
bất cứ ai có thể đưa ra bất kỳ đề xuất về những gì là gây ra SO, hoặc làm thế nào để gỡ lỗi nó?
PS. Tôi đã tăng không gian ngăn xếp dành riêng cho hàng trăm Mb
và sự cố vẫn tiếp diễn. Tôi đã cố gắng bỏ qua các cuộc gọi chkstk()
trong dissasembler nhưng trong tai nạn chương trình. Kiểm tra ngăn xếp bắt đầu từ địa chỉ 0x354000
và lặp lại xuống 0x2D2000
nơi nó gặp sự cố khi truy cập trang bảo vệ. Địa chỉ dưới cùng của ngăn xếp là 0x282000
.
Bạn đang sử dụng các tùy chọn trình biên dịch nào trong mỗi trường hợp? Hãy thử biên dịch tất cả các cờ cảnh báo lỗi mà bạn có thể nghĩ là đã bật. Bước đầu tiên tôi có xu hướng sử dụng '-std -check all -Warn all, nodec, interfaces, declarationations -gen_interfaces -g -C -traceback -fpe0 -fp-stack-check' với ifort. – Chris
Tôi hy vọng bạn đã phát hiện ra lỗi số học của riêng bạn bây giờ, nhưng tổng số 832 byte của bạn phải là 832 bit. Nó không phải luôn luôn là trường hợp, hoặc là, mỗi nhân vật được đại diện bởi một byte: điều này có xu hướng khác nhau với trình biên dịch và nền tảng. Với một trình biên dịch cập nhật, kích thước của các 'đơn vị lưu trữ' khác nhau có sẵn như là các hằng số được định nghĩa trong mô-đun nội tại ISO_FORTRAN_ENV. –
Cả hai ý kiến trên đều cho tôi một cái gì đó để làm việc. Tôi sẽ điều tra thêm. Có thể có một tham nhũng ngăn xếp mà 'CVF' không bắt và bằng cách nào đó thổi qua nó. Có rất nhiều điều xảy ra trong mã như nhiều nhà phát triển đã chạm vào nó từ những năm 80 khi nó được viết lần đầu tiên. – ja72