« PDF作成の自動化・省力化 [4] (改良版CtrlSaveas.exeをVBから使う) | トップページ | PDF作成の自動化・省力化 [6] (CADのPDF化 : LISPスクリプト部分) »

2009年6月30日 (火)

PDF作成の自動化・省力化 [5] (CADのPDF化 : C言語部分)

今回の仕事の顧客はCAD図面のPDF化もしています。(利用しているCADは"IJCAD"というソフトです。バージョンは6)

やはり現状では手作業でPDFプリンタに印刷してPDF化しているわけです。この作業もCtrlSaveas.exeとVB6との組み合わせで実現したのと同様の考え方で自動化・省力化を試みてみました。(やりたかったのはこれで、"PDF作成の自動化・省力化 [1]~[4]" はそのための準備でありました。CコンパイラにVC++ Ver6を使ったのもIJCADの機能拡張にはこのバージョンが適切との情報によります。)

IJCADのC言語プログラミングインターフェース規格"SDS"に従ってCの関数を作成し(DLLにまとめられます)、IJCADのスクリプト言語であるLISPからそれを呼んでみます。

まずはC言語部分。
---------------------------------------------------------------------------
[SdsTest.dllのソースSdsTest.cppの抜粋]

static struct func_def func_table[] =        {
  {"sdstest_createprocess", sdstest_createprocess},
  {"sdstest_waitforprocess", sdstest_waitforprocess}
                                             };

/*
*  外部プログラムの起動。
*  LISPからの使い方:
*    (sdstest_createprocess コマンド [任意の個数のコマンドパラメータ])
*  戻り値:プロセスハンドル エラー時は0
*/
static int sdstest_createprocess(struct sds_resbuf *rb){
  struct sds_resbuf *p;
  char  commandline[1024];
  char  param[256];
  STARTUPINFO  stinf;
  PROCESS_INFORMATION  procinf;
  HANDLE  hProcess = 0;    // Process Handle

  // 最初のパラメータはコマンドライン文字列
  p = rb;
  if (p != NULL && p->restype == SDS_RTSTR){
    strcpy(commandline, p->resval.rstring);
  } else {
    sds_printf("\nコマンドライン文字列が不正です。");
    return sds_retint(0);
  }
  // 残りのパラメータはコマンドラインの引数
  for (p=p->rbnext; p!= NULL; p=p->rbnext){
    if (p->restype == SDS_RTSHORT){
      sprintf(param, " %d", p->resval.rint);
    } else if (p->restype == SDS_RTLONG){
      sprintf(param, " %ld", p->resval.rlong);
    } else if (p->restype == SDS_RTSTR){
      sprintf(param, " \"%s\"", p->resval.rstring);
    } else if (p->restype == SDS_RTREAL){
      sprintf(param, " %f", p->resval.rreal);
    } else {
      continue;
    }
    strcat(commandline, param);
  }

  // コマンドを起動
  sds_printf("\nsdstest_createprocess: %s\n", commandline);
  memset(&stinf, 0, sizeof(STARTUPINFO));
  stinf.cb = sizeof(STARTUPINFO);
  if (CreateProcess(NULL, commandline, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
    NULL, NULL, &stinf, &procinf) == 0){
    // エラー
    sds_printf("\nsdstest_createprocessはコマンド%sの起動に失敗しました", commandline);
    return sds_retint(0);
  } else {
    hProcess = procinf.hProcess;
  }
  sds_printf("\nプロセスハンドル=%ld", hProcess);
  return sds_retint((int)hProcess);
}

/*
*  プロセスが終了するのを待つ
*  LISPからの使い方:
*    (sdstest_waitforprocess プロセスハンドル タイムアウト秒)
*  戻り値:0=プロセスの正常終了 1=タイムアウト 2=その他エラー
*/
static int sdstest_waitforprocess(struct sds_resbuf *rb){
  struct sds_resbuf *p;
  DWORD  timeout;
  int    ret = 2;
  HANDLE  hProcess;
  DWORD  res;

  p = rb;
  if (p != NULL && p->restype == SDS_RTSHORT){
    hProcess = (HANDLE)(p->resval.rint);
    p = p->rbnext;
  } else if (p != NULL && p->restype == SDS_RTLONG){
    hProcess = (HANDLE)(p->resval.rlong);
    p = p->rbnext;
  } else {
    sds_printf("\nプロセスハンドルが不正です。");
    return sds_retint(ret);
  }
  sds_printf("\nプロセスハンドル=%ld", hProcess);
  if (p != NULL && p->restype == SDS_RTSHORT){
    timeout = p->resval.rint;
  } else if (p != NULL && p->restype == SDS_RTLONG){
    timeout = p->resval.rlong;
  } else {
    sds_printf("\nタイムアウト時間が不正です。");
    return sds_retint(ret);
  }
  timeout *= 1000;

  // プロセスの終了を待つ
  if ((res = WaitForSingleObject(hProcess, (timeout==0 ? INFINITE : timeout))) == WAIT_OBJECT_0){
    sds_printf("\nプロセスが正常に終了しました。");
    ret = 0;
  } else if (res == WAIT_TIMEOUT){
    sds_printf("\nプロセス終了がタイムアウトしました。");
    ret = 1;
  } else {
    sds_printf("\nその他エラー");
    ret = 2;
  }
  CloseHandle(hProcess);

  return sds_retint(ret);
}

« PDF作成の自動化・省力化 [4] (改良版CtrlSaveas.exeをVBから使う) | トップページ | PDF作成の自動化・省力化 [6] (CADのPDF化 : LISPスクリプト部分) »

ソフトウエア」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: PDF作成の自動化・省力化 [5] (CADのPDF化 : C言語部分):

« PDF作成の自動化・省力化 [4] (改良版CtrlSaveas.exeをVBから使う) | トップページ | PDF作成の自動化・省力化 [6] (CADのPDF化 : LISPスクリプト部分) »