2009-08-07 34 views
33

Tôi có tệp nguồn C++ và tệp nguồn Python. Tôi muốn tệp nguồn C++ có thể sử dụng nội dung của tệp nguồn Python dưới dạng chuỗi ký tự lớn. Tôi có thể làm một cái gì đó như thế này:C/C++, bạn có thể #bao gồm một tệp vào một chuỗi ký tự không?

char* python_code = " 
#include "script.py" 
" 

Nhưng điều đó sẽ không hoạt động vì cần phải có \ 's ở cuối mỗi dòng. Tôi có thể sao chép và dán thủ công nội dung của mã Python và bao quanh mỗi dòng với dấu ngoặc kép và kết thúc \ n, nhưng điều đó thật xấu. Mặc dù nguồn python sẽ được biên dịch thành ứng dụng C++ của tôi, tôi muốn giữ nó trong một tệp riêng biệt vì nó được tổ chức tốt hơn và hoạt động tốt hơn với trình chỉnh sửa (emacs không đủ thông minh để nhận ra rằng C chuỗi chữ là mã python và chuyển sang chế độ python trong khi bạn đang ở trong đó).

Xin đừng đề nghị tôi sử dụng PyRun_File, đó là những gì tôi đang cố gắng để tránh ở nơi đầu tiên;)

+0

Tôi biết đây là bản sao. –

+3

Nếu đó là bản sao, bạn có thể cung cấp liên kết không? Tôi nhìn xung quanh và không thấy bất cứ điều gì với các thuật ngữ tìm kiếm của tôi. –

+0

Ngoài ra, là phiên bản trăn trước cụ thể? Bởi vì nó là một câu hỏi tổng quát hơn. –

Trả lời

35

C/C++ hành vi Preprocessor trong các đơn vị của thẻ, và một chuỗi chữ là một đơn mã thông báo. Như vậy, bạn không thể can thiệp vào giữa một chuỗi chữ như thế.

Bạn preprocess thể script.py vào một cái gì đó như:

"some code\n" 
"some more code that will be appended\n" 

và #include đó, tuy nhiên. Hoặc bạn có thể sử dụng xxd​ -i để tạo một mảng tĩnh C sẵn sàng để đưa vào.

+11

+1 cho xxd. Kịch bản có thể không thực sự cần phải là một chuỗi chữ. –

+0

Làm thế nào để bạn xử lý trước script.py theo cách đó? Tôi không thấy một cách để làm điều đó với CPP. Trừ khi bạn có nghĩa là với một công cụ bên ngoài như sed trong trường hợp đó quá. –

+0

Một công cụ bên ngoài, vâng. Bạn không thể làm những gì bạn muốn chỉ với CPP. – bdonlan

1

Bạn sẽ phải thực hiện một số xử lý của riêng bạn trên mã Python, để xử lý mọi dấu ngoặc kép, dấu gạch chéo ngược, dấu vết và những thứ khác có thể xuất hiện trong đó. Bạn có thể đồng thời chuyển dòng mới thành \ n (hoặc dấu gạch chéo ngược-thoát chúng) và thêm dấu ngoặc kép ở hai đầu. Kết quả sẽ là một tệp tiêu đề được tạo từ tệp nguồn Python, sau đó bạn có thể #include. Sử dụng quá trình xây dựng của bạn để tự động hóa việc này, để bạn vẫn có thể chỉnh sửa nguồn Python như Python.

1

Bạn có thể sử dụng Cog như một phần của quá trình xây dựng (để thực hiện xử lý trước và nhúng mã). Tôi thừa nhận rằng kết quả của điều này có lẽ không lý tưởng, kể từ đó bạn sẽ thấy mã ở cả hai nơi. Nhưng bất cứ lúc nào tôi thấy "Python", "C++" và "Preprocessor" trong khoảng cách gần nhau, tôi cảm thấy nó đáng được đề cập đến.

-8

Sử dụng fopen, getlinefclose.

+2

Tương đương với PyRun_File. Ý tưởng là để gói nó vào thực thi tại thời gian biên dịch vì vậy tôi không phải làm điều đó. –

+1

Điều này sẽ giúp bạn có được nội dung thời gian chạy của tệp trên máy thực thi chứ không phải nội dung biên dịch của tệp trên máy xây dựng. –

4

Cách tốt nhất để làm điều gì đó như thế này là bao gồm tệp dưới dạng tài nguyên nếu môi trường/bộ công cụ của bạn có khả năng đó.

Nếu không (như hệ thống nhúng, v.v.), bạn có thể sử dụng tiện ích bin2c (chẳng hạn như http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c). Nó sẽ lấy một biểu diễn nhị phân của tệp và nhổ ra một tệp nguồn C bao gồm một mảng các byte được khởi tạo cho dữ liệu đó. Bạn có thể cần phải làm một số tinh chỉnh của công cụ hoặc tập tin đầu ra nếu bạn muốn các mảng được '\ 0' chấm dứt.

Kết hợp chạy tiện ích bin2c vào tệp makefile của bạn (hoặc dưới dạng bước dựng sẵn của bất kỳ thứ gì bạn đang sử dụng để thúc đẩy bản dựng của mình). Sau đó, chỉ cần có các tập tin được biên dịch và liên kết với các ứng dụng của bạn và bạn có chuỗi của bạn (hoặc bất kỳ hình ảnh khác của tập tin) ngồi trong một đoạn bộ nhớ được đại diện bởi mảng.

Nếu bạn bao gồm tệp văn bản dưới dạng chuỗi, một điều bạn nên biết là kết thúc dòng có thể không khớp với những chức năng mong đợi - đây có thể là một thứ khác bạn muốn thêm vào tiện ích bin2c hoặc bạn sẽ muốn đảm bảo mã của bạn xử lý bất kỳ kết thúc dòng nào trong tệp đúng cách. Có thể sửa đổi tiện ích bin2c để có một '-s' chuyển đổi cho biết bạn muốn một tập tin văn bản kết hợp như là một chuỗi để kết thúc dòng sẽ được bình thường hóa và một byte không sẽ được ở cuối mảng.

9

Điều này sẽ không giúp bạn có được tất cả các cách đó, nhưng nó sẽ giúp bạn có được khá gần chết tiệt.

Giả sử script.py chứa này:

print "The current CPU time in seconds is: ", time.clock() 

Đầu tiên, quấn nó lên như thế này:

STRINGIFY(print "The current CPU time in seconds is: ", time.clock()) 

Sau đó, ngay trước khi bạn có nó, làm như sau:

#define STRINGIFY(x) #x 

const char * script_py = 
#include "script.py" 
; 

Có có lẽ là một câu trả lời thậm chí còn chặt chẽ hơn thế, nhưng tôi vẫn đang tìm kiếm.

+0

bạn Thưa ngài, có một cookie! 2 năm nhảy múa xung quanh vấn đề –

+1

Tôi đã có một trường hợp (chắc chắn hiếm) mà đôi khi tôi cần phải bao gồm cùng một tập tin như mã, và đôi khi như một chuỗi (không hỏi;)). Vì vậy, tôi đã thêm vào tệp được đính kèm '#ifndef STRINGIFY \ n # define STRINGIFY (x) x \ n # endif' và khi tôi muốn bao gồm nó làm mã, tôi đảm bảo STRINGIFY không được xác định. Một cách kỳ diệu nó cũng hoạt động đối với các tệp đa dòng! –

-2

Sau đây là cách tự động chuyển đổi với cmd.exe

------ html2h.bat ------

@echo off 
echo const char * html_page = "\ 
sed "/.*/ s/$/ \\n\\/" ../src/page.html | sed s/\"/\\\x22/g 
echo. 
echo "; 

Nó được gọi như

cmd /c "..\Debug\html2h.bat" > "..\debug\src\html.h" 

và được đính kèm theo mã bởi

#include "../Debug/src/html.h" 
printf("%s\n", html_page); 

Đây là cách tiếp cận khá phụ thuộc vào hệ thống nhưng, như hầu hết mọi người, tôi không thích đổ bóng hex.

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