hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 809|回复: 0

单文件混合语言编程

[复制链接]

533

主题

533

帖子

1826

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1826
发表于 2024-2-24 17:30:11 | 显示全部楼层 |阅读模式
今天阅读了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 <stdio.h>
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
-----------------------------------------------------------------------------------------------------------------------------


注意:由于本论坛会对美元符号解释为公式,故文中所有的美元符号都写成斜杠加美元符号。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-2 16:44 , Processed in 0.058345 second(s), 21 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

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