2010-09-06 34 views
9

Tôi đã thử nghiệm với việc nhúng các ngôn ngữ kịch bản khác nhau trong một ứng dụng C++, hiện tại tôi đang thử Stackless Python 3.1. Tôi đã thử một số hướng dẫn và ví dụ, những gì tôi có thể tìm thấy, để thử và chạy một kịch bản đơn giản từ một ứng dụng.Tại sao lỗi Python/C gặp lỗi trên PyRun_SimpleFile?

Py_Initialize(); 

FILE* PythonScriptFile = fopen("Python Scripts/Test.py", "r"); 
if(PythonScriptFile) 
{ 
    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py"); 
    fclose(PythonScriptFile); 
} 

Py_Finalize(); 

Đối với một số lý do kỳ quặc, chạy mảnh này kết quả mã trong một vi phạm truy cập tại địa chỉ:

PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py"); 

Tôi đã tìm kiếm trực tuyến cho những người khác với một vấn đề tương tự và chỉ có một được tìm thấy. Giải pháp duy nhất của họ là giải pháp mà dường như chỉ có thể có trong phiên bản cũ của Python: Tạo đối tượng tệp python và trả về FILE* từ đối tượng tệp python đó thành PyRun_SimpleFile. Tuy nhiên, các hàm gọi hàm này không có sẵn, API Python 3.1 tạo các đối tượng tệp từ một bộ mô tả tệp và trả về các bộ mô tả tệp, nhưng hàm PyRun_SimpleFile vẫn yêu cầu một FILE*.

Tôi không biết làm cách nào để chạy bất kỳ tập lệnh nào từ tệp, thiếu tải toàn bộ tệp vào bộ nhớ theo cách thủ công và chạy nó dưới dạng chuỗi khổng lồ, chắc chắn không phải là giải pháp thiết thực.

Điều gì mang lại? Làm cách nào tôi có thể thực hiện tác vụ này nếu API có lỗi nội bộ?

Cập nhật: Tôi đã quản lý để xây dựng Stackless Python 3.1 từ nguồn và sự cố vẫn hoàn toàn không thay đổi, mặc dù sử dụng cùng một thư viện thời gian chạy C. Cả dự án của tôi và nguồn Stackless Python 3.1 đều được xây dựng với trình biên dịch C++ của Visual Studio 2010 và thời gian chạy C. Tôi không còn có bất kỳ ý tưởng nào về những gì có thể giải quyết được vấn đề này, thiếu sửa đổi Python để sử dụng tên tệp và không phải là một TẬP_TIN *. Một cách giải quyết khủng khiếp khác.

Trả lời

3

Điều này nghe giống như sự cố về API không khớp. Nếu mã của bạn và thời gian chạy Python được biên dịch với các trình biên dịch khác nhau, hoặc thậm chí các tùy chọn trình biên dịch khác nhau, thì truy cập vào FILE * có thể dẫn đến vi phạm truy cập. Bạn có thể kiểm tra kỹ xem bạn đã xây dựng mã C đúng cách không?

Bạn đề cập đến việc bạn đang nhúng Python vào ứng dụng C++ của mình. Hãy nhớ rằng Python là mã C, được biên dịch thành mã C. Có lẽ đó là nguồn gốc của vấn đề?

+0

Aye, tôi không xây dựng thư viện Stackless Python 3.1 của tôi. Tôi đã đọc rằng vấn đề rất có thể là việc sử dụng các FILE * từ các thời gian chạy khác nhau, do đó giải pháp thay thế là cho phép thư viện Python tạo FILE * và trả về nó để sử dụng làm đối số cho hàm. Vì vậy, sau đó, tôi không có tùy chọn, nhưng để có được nguồn và xây dựng Stackless Python 3.1 bản thân mình? –

+0

Nếu bạn có thể xây dựng mã C, thì bạn sẽ không gặp bất kỳ khó khăn nào với mã Stackless. –

5

Mã của bạn hoạt động chính xác trên phiên bản Python 2.6 đã cài đặt của tôi. Tôi cũng xây dựng stackless 3.1.2 từ nguồn và nó hoạt động chính xác. Điều này là với g ++ 4.4.3 trên Ubuntu 10.04. Nếu bạn đang ở trên các cửa sổ, bạn có thể muốn kiểm tra xem cả stackless và mã của bạn được xây dựng dựa trên cùng một thời gian chạy C.

+0

Vâng, đó là nơi tôi đang gặp rắc rối. Tôi biết thời gian chạy C là khác nhau. Tôi đang sử dụng Visual Studio 2010 và tôi khá chắc chắn hầu hết các nhị phân Python được xây dựng với Visual Studio 2008. Tôi đã cố gắng xây dựng nguồn Stackless Python 3.1, nhưng tôi không hoàn toàn chắc chắn thư viện, DLL và tiêu đề nào được cần. Chưa kể có một số vấn đề liên quan đến một số mô-đun mở rộng không xây dựng do thiếu tệp. Các tập tin batch được cung cấp để xây dựng chúng phụ thuộc vào một số tập tin còn thiếu khác, giống như có SVN được cài đặt. –

+0

@Sion: Thật không may, không có gì tôi thực sự có thể cung cấp bên cạnh việc nói "kiểm tra tài liệu" và "chúc may mắn". Tôi không có quyền truy cập vào một máy phát triển Windows, hãy để một mình VS2010. Có cách nào để viết một wrapper nhỏ cho các phần liên quan của stdio được xây dựng với phiên bản studio hình ảnh chính xác? –

+0

Trợ giúp được đánh giá là không kém, mặc dù vào thời điểm này thậm chí cùng một trình biên dịch và thời gian chạy không có tác dụng giải quyết vấn đề. Tôi rất có thể phải cố gắng và liên hệ trực tiếp với các nhà phát triển hoặc các chuyên gia Python khác. –

12

Tôi đã nhận được một vụ tai nạn tương tự & đã làm dưới đây:

PyObject* PyFileObject = PyFile_FromString("test.py", "r"); 
    PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "test.py", 1); 

Lưu ý rằng đây là trong python 2.7 mặc dù. Tôi không biết liệu API có thay đổi trong 3.x.

+0

Như bạn nghi ngờ, điều này không hoạt động với Python 3. – MasterMind

9

này làm việc cho tôi trên Python 3:

PyObject *obj = Py_BuildValue("s", "test.py"); 
FILE *file = _Py_fopen_obj(obj, "r+"); 
if(file != NULL) { 
    PyRun_SimpleFile(file, "test.py"); 
} 

Tôi hy vọng nó sẽ có ích.

+2

Làm việc cho tôi, nhưng với sửa đổi nhỏ: FILE * file = _Py_fopen ("test.py", "r +"); PyRun_SimpleFile (tệp, "test.py"); Điều này phải được đánh dấu là câu trả lời. – MasterMind

+1

@MasterMind: OP của câu trả lời rõ ràng là muốn gọi hàm '_Py_fopen_obj' thay vì hàm' _Py_fopen'. Tôi đã chỉnh sửa câu trả lời cho phù hợp (vì vậy mã từ câu trả lời giờ đây sẽ hoạt động ra khỏi hộp). Tuy nhiên, giải pháp của bạn có vẻ dễ dàng hơn/nhẹ hơn. Vì lý do nào đó, cả hai giải pháp * chỉ * hoạt động nếu tôi đã khai báo 'const char *' filepath-variable ** sau ** hàm 'Py_Initialize()' hoặc nếu tôi đặt trực tiếp chuỗi giống như bạn đã làm thí dụ. (Thành thật mà nói: Trình bao bọc Python C++ là một nỗi đau và có thể đơn giản hơn rất nhiều) – mozzbozz

0

Nếu bạn xây dựng thử nghiệm với VC 2010, bạn chắc chắn sẽ gặp sự cố - VC9 (VS 2008) và VC10 (VS 2010) có các tệp DLL hỗ trợ không tương thích lẫn nhau thường được yêu cầu (triển khai printf, tệp i/o và sắp xếp đó điều).Bạn không thể trộn chúng nếu chúng bao gồm các thư viện chuẩn, mà xây dựng python làm.

Bạn luôn có tùy chọn sử dụng gcc (ví dụ: Cygwin hoặc mingw) hoặc tải xuống Visual Studio 2008 express, điều này sẽ hoạt động tốt để thử nghiệm trong quá trình nhúng python. Tôi đã sử dụng cả hai với tiêu chuẩn Python 2.7.6 xây dựng.

0

Và những gì về giải pháp này:

Py_SetProgramName(argv[0]); 
Py_Initialize(); 
PyRun_SimpleString("execfile(\"ex30.py\")"); 
Py_Finalize(); 

đâu ex30.py nó tên của kịch bản python Tôi đang chạy.

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