2011-10-05 30 views
10

Tôi có một ứng dụng C# sử dụng một DLL C++ không được quản lý. Tôi đã tìm thấy một vụ tai nạn mà chỉ xảy ra trong WinXP (không phải Win7) khi bộ nhớ tôi đang quay trở lại từ C + + DLL là quá lớn.Giới hạn bộ nhớ trong WinXP khi nhận được cuộc gọi lại từ một DLL C++ trong C# là gì?

Luồng cơ bản là C# bắt đầu một hoạt động trong DLL C++ bằng cách gọi hàm khởi động, trong đó nó cung cấp gọi lại. C++ DLL sau đó thực hiện các hoạt động và đổ thông tin đăng nhập vào một bộ đệm văn bản. Khi hoạt động được hoàn thành C++ DLL gọi callback và vượt qua bộ đệm văn bản như một tham số:

C++:

typedef void (CALLBACK *onfilecallbackfunc_t)(LPCWSTR); 
DLL_API void NWAperture_SetOnFileCallback(onfilecallbackfunc_t p_pCallback); 

l_pFileCallback(_wstringCapture.c_str()); 

C#:

public delegate void FileCallback([MarshalAs(UnmanagedType.LPWStr)] string buffer); 
public static extern void SetOnFileCallback(FileCallback fileCallback); 

private void OnFile(string buffer); 

này hoạt động tốt trong Win7, nhưng trong WinXP nếu bộ đệm quá lớn, nó bị treo. Tôi không chắc chắn về kích thước chính xác gây ra điều này nhưng tôi đã đặt một giới hạn 8MB vào nó và vụ tai nạn đã biến mất.

Có ai biết giới hạn về số lượng bộ nhớ có thể được chuyển giữa C++ và C# như thế này trong WinXP không? Hoặc tôi đã hoàn toàn hiểu lầm vấn đề này và có một lời giải thích hợp lý hơn?

Cập nhật: Tôi cần phải cụ thể hơn - điều này xảy ra trên cùng một máy tính có khởi động kép WinXP và Win7, cả hai hệ điều hành 32 bit.

+0

+1 cho câu hỏi thú vị. Tôi cũng muốn biết câu trả lời cho điều này. – Polynomial

+0

Bạn nói rằng nó chỉ xảy ra trên Windows XP? Đây có phải là một hộp XP x86 như trái ngược với một Win7 x64? Nếu bạn đang xử lý kiến ​​trúc 64 bit 32 bit, đó có thể là nguồn gốc của sự cố ... –

+0

Mở rộng nhận xét của Steve, bạn đã cố gắng biên dịch mã C# của bạn nhắm mục tiêu x86 thay vì AnyCPU chưa? –

Trả lời

2

Vì vậy, cuối cùng hóa ra tôi đã là một thằng ngốc. Để làm cho nhật ký lớn nhưng tăng tốc độ kiểm tra, tôi đã nhấp vào nút hủy, được gọi là hàm trong DLL C++ đã dừng thực thi và gọi hàm gọi lại với lỗi 'hủy bỏ' và bất kỳ nhật ký nào đã được ghi lại. Nhưng khi tôi thực hiện điều này, việc thực hiện không dừng ngay lập tức, vì vậy khi cuộc gọi lại với nhật ký đang được tiến hành, mã C++ có thể tìm cách thêm vào nhật ký. Điều này gây ra sự bất ổn tôi đã nhìn thấy.

Tôi đã sửa lỗi bằng cách sử dụng phần quan trọng xung quanh nhật ký.

0

Tôi không biết bất kỳ giới hạn cứng nào do Windows hoặc NETFX đặt ra, nhưng tôi rất nghi ngờ rằng khối lượng dữ liệu được trả lại từ ứng dụng C++ của bạn có thể hoàn toàn tùy ý và điều này có thể dẫn đến hành vi dễ bay hơi.

Tôi đặc biệt khuyên bạn nên xem xét ghi dữ liệu nhật ký của mình vào một tệp trong thành phần gốc của bạn và sau đó đọc tệp từ mã được quản lý của bạn. Bằng cách này, nó không quan trọng bao nhiêu dữ liệu được đăng nhập, mã được quản lý của bạn có thể phân tích nó thông qua nó mà không đáng lo ngại về việc thổi đống của nó.

1

Bạn có thể hết bộ nhớ tiếp giáp trước khi thực sự hết RAM. Đây là một phần lớn trong việc sử dụng bộ đệm Array. LinkedLists (hoặc mảng sử dụng chunking) giúp giảm thiểu vấn đề này, bởi vì không gian bạn cần không cần phải tiếp giáp.

Vì vậy, trừ khi ứng dụng của bạn đang sử dụng hơn 2 GB RAM, vấn đề của bạn có nhiều khả năng phân mảnh bộ nhớ hơn bất kỳ thứ gì khác.

Windows 7 có thể quản lý RAM khác với Windows XP, đó có thể là lý do bạn không gặp sự cố ở đó. Nhưng đẩy nhiều dữ liệu hơn và tôi chắc chắn bạn sẽ gặp phải vấn đề tương tự ở đó.

Bạn có thể thiết lập perfmon để theo dõi/đăng nhập sử dụng bộ nhớ của hệ thống và trình quản lý tác vụ để theo dõi ứng dụng của bạn.

Các vấn đề liên quan