找回密码
 欢迎注册
查看: 7673|回复: 0

[分享] 单文件混合语言编程

[复制链接]
发表于 2013-1-15 23:35:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
今天阅读了GMP的代码,发现许多有趣的东西,看到了一种在一个文件中混合多种语言的技巧。这里的混合语言编程不是指C中嵌入汇编语言的那种,C中嵌入汇编语言还是符合某种C编译器语言语法的。这里的混合语言具有这样的特点,文件类型是A语言源代码,但在文件中A嵌入B语言源代码。比如 1. 批处理中嵌入perl代码,下面的例子是我的一个老大(美国人)写的。这里的关键是"#!Perl/bin/perl -w" 和 "%perl% -x %0 %*" 这2句. 第2句使用参数 -x 调用自己,按照perl命令行参数的规则,则#!Perl前的代码将忽略。 ----------------------------------- @rem = '--*-Perl-*-- @echo off rem is perl on path? perl -v > nul 2>&1 if %errorlevel% equ 0 ( set perl=perl ) ELSE ( set perl=c:\svg_cygwin_db\bin\perl.exe ) if "%OS%" == "Windows_NT" goto WinNT echo PERL=%perl% %perl% -x "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl :WinNT %perl% -x %0 %* if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl if %errorlevel% == 9009 echo You do not have Perl in your PATH. if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul goto endofperl @rem '; #!Perl/bin/perl -w #line 22 use FindBin qw(\$RealDir); use lib "\$RealDir/lib"; use RTH; RTH::run(); __END__ :endofperl ------------------------------------------------ 2.shell脚本中嵌入c语言源代码。 这是在GMP源码包中的config.guess中看到了。这个文件的类型是shell脚本,从第一句"#! /bin/sh" 可以看出。但在这个文件文件中混入许多c代码。例如:"cat >\$dummy.c <<\EOF" 下面的行就是标准的c代码,直到EOF为止,在EOF下面的代码则是将这段c代码编译并运行编译好的程序。 --------------------------------------------------------------- dummy=my_test cat >\$dummy.c <<\EOF #include struct { int n; /* force 4-byte alignment */ char a[8]; } getpvr = { 0, { 0x7c, 0x7f, 0x42, 0xa6, /* mfpvr r3 */ 0x4e, 0x80, 0x00, 0x20, /* blr */ } }; int main () { unsigned (*fun)(); unsigned pvr; /* a separate "fun" variable is necessary for gcc 2.95.2 on MacOS, it gets a compiler error on a combined cast and call */ fun = (unsigned (*)()) getpvr.a; pvr = (*fun) (); switch (pvr >> 16) { case 0x0001: puts ("powerpc601"); break; case 0x0003: puts ("powerpc603"); break; case 0x0004: puts ("powerpc604"); break; case 0x0006: puts ("powerpc603e"); break; case 0x0007: puts ("powerpc603e"); break; /* 603ev */ case 0x0008: puts ("powerpc750"); break; case 0x0009: puts ("powerpc604e"); break; case 0x000a: puts ("powerpc604e"); break; /* 604ev5 */ case 0x000c: puts ("powerpc7400"); break; case 0x0041: puts ("powerpc630"); break; case 0x0050: puts ("powerpc860"); break; case 0x8000: puts ("powerpc7450"); break; case 0x8001: puts ("powerpc7455"); break; case 0x8002: puts ("powerpc7457"); break; case 0x8003: puts ("powerpc7447"); break; /* really 7447A */ case 0x800c: puts ("powerpc7410"); break; } return 0; } EOF if (\$CC_FOR_BUILD \$dummy.c -o \$dummy) >/dev/null 2>&1; then # This style construct is needed on AIX 4.3 to suppress the SIGILL error # from (*fun)(). Using \$SHELL -c ./\$dummy 2>/dev/null doesn't work. { x=`./\$dummy`; } 2>/dev/null if test -n "\$x"; then exact_cpu=\$x fi fi ----------------------------------------------------------------------------------------------------------------------------- 注意:由于本论坛会对美元符号解释为公式,故文中所有的美元符号都写成斜杠加美元符号。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-10-18 14:43 , Processed in 0.020973 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表